@eva/plugin-ui 2.1.0-beta.1 → 2.1.0-beta.10

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.
@@ -7,26 +7,28 @@ var pluginRendererGraphics = require('@eva/plugin-renderer-graphics');
7
7
  var pixi_js = require('pixi.js');
8
8
  var ui = require('@pixi/ui');
9
9
 
10
- /** UI 形状类型枚举 */
11
- exports.UIShapeType = void 0;
12
- (function (UIShapeType) {
13
- UIShapeType["RECT"] = "rect";
14
- UIShapeType["CIRCLE"] = "circle";
15
- UIShapeType["ELLIPSE"] = "ellipse";
16
- UIShapeType["ROUNDED_RECT"] = "roundedRect";
17
- })(exports.UIShapeType || (exports.UIShapeType = {}));
10
+ /** Shape primitive type enum */
11
+ exports.ShapeType = void 0;
12
+ (function (ShapeType) {
13
+ ShapeType["RECT"] = "rect";
14
+ ShapeType["CIRCLE"] = "circle";
15
+ ShapeType["ELLIPSE"] = "ellipse";
16
+ ShapeType["ROUNDED_RECT"] = "roundedRect";
17
+ })(exports.ShapeType || (exports.ShapeType = {}));
18
+ /** Backward-compatible enum value alias for existing TypeScript consumers. */
19
+ const UIShapeType = exports.ShapeType;
18
20
  /**
19
- * UI 组件
21
+ * Shape 组件
20
22
  *
21
23
  * 基于 `@eva/plugin-renderer-graphics` 实现 rect/circle/ellipse/roundedRect 的
22
24
  * 矢量绘制,支持纯色 / linear-gradient 填充与描边。`shapes` 数组允许在同一个
23
25
  * GameObject 上层叠多个形状。
24
26
  */
25
- class UI extends eva_js.Component {
27
+ class Shape extends eva_js.Component {
26
28
  constructor() {
27
29
  super(...arguments);
28
30
  /** 实例侧 componentName,DSL 序列化时使用 */
29
- this.componentName = 'UI';
31
+ this.componentName = 'Shape';
30
32
  this.shapes = [];
31
33
  }
32
34
  /** 编辑器 Inspector 元数据,主仓 ComponentInspector 通过静态方法读取 */
@@ -43,7 +45,7 @@ class UI extends eva_js.Component {
43
45
  { name: 'radius', type: 'number', isArray: false },
44
46
  ];
45
47
  return {
46
- name: UI.componentName,
48
+ name: Shape.componentName,
47
49
  type: 'object',
48
50
  isArray: false,
49
51
  isFolder: true,
@@ -176,12 +178,12 @@ class UI extends eva_js.Component {
176
178
  const x = style.x || 0;
177
179
  const y = style.y || 0;
178
180
  switch (type) {
179
- case exports.UIShapeType.RECT:
180
- case exports.UIShapeType.ROUNDED_RECT:
181
+ case exports.ShapeType.RECT:
182
+ case exports.ShapeType.ROUNDED_RECT:
181
183
  return { width: style.width, height: style.height, x, y };
182
- case exports.UIShapeType.CIRCLE:
184
+ case exports.ShapeType.CIRCLE:
183
185
  return { width: style.radius * 2, height: style.radius * 2, x, y };
184
- case exports.UIShapeType.ELLIPSE:
186
+ case exports.ShapeType.ELLIPSE:
185
187
  return { width: style.width, height: style.height, x, y };
186
188
  default:
187
189
  return { width: 100, height: 100, x, y };
@@ -207,32 +209,27 @@ class UI extends eva_js.Component {
207
209
  }
208
210
  /** 绘制单个形状 */
209
211
  drawShape(graphics, type, style) {
212
+ var _a;
210
213
  if (style.alpha !== undefined) {
211
214
  graphics.alpha = style.alpha;
212
215
  }
213
- if (style.stroke && style.lineWidth !== undefined) {
214
- graphics.setStrokeStyle({ color: style.stroke, width: style.lineWidth });
215
- }
216
- else if (style.stroke) {
217
- graphics.setStrokeStyle({ color: style.stroke, width: 1 });
218
- }
219
216
  switch (type) {
220
- case exports.UIShapeType.RECT:
217
+ case exports.ShapeType.RECT:
221
218
  this.drawRect(graphics, style);
222
219
  break;
223
- case exports.UIShapeType.CIRCLE:
220
+ case exports.ShapeType.CIRCLE:
224
221
  this.drawCircle(graphics, style);
225
222
  break;
226
- case exports.UIShapeType.ELLIPSE:
223
+ case exports.ShapeType.ELLIPSE:
227
224
  this.drawEllipse(graphics, style);
228
225
  break;
229
- case exports.UIShapeType.ROUNDED_RECT:
226
+ case exports.ShapeType.ROUNDED_RECT:
230
227
  this.drawRoundedRect(graphics, style);
231
228
  break;
232
229
  default:
233
230
  console.warn(`Unknown shape type: ${type}`);
234
231
  }
235
- if (style.fill) {
232
+ if (style.fill !== undefined) {
236
233
  if (typeof style.fill === 'string' && style.fill.includes('linear-gradient')) {
237
234
  const gradientInfo = this.parseLinearGradient(style.fill);
238
235
  if (gradientInfo) {
@@ -249,6 +246,12 @@ class UI extends eva_js.Component {
249
246
  graphics.fill(style.fill);
250
247
  }
251
248
  }
249
+ if (style.stroke !== undefined) {
250
+ graphics.stroke({
251
+ color: style.stroke,
252
+ width: (_a = style.lineWidth) !== null && _a !== void 0 ? _a : 1,
253
+ });
254
+ }
252
255
  }
253
256
  drawRect(graphics, style) {
254
257
  const x = style.x || 0;
@@ -330,7 +333,7 @@ class UI extends eva_js.Component {
330
333
  }
331
334
  }
332
335
  /** 组件名称 */
333
- UI.componentName = 'UI';
336
+ Shape.componentName = 'Shape';
334
337
 
335
338
  /**
336
339
  * Eva GameObject -> PIXI.Container resolver.
@@ -454,7 +457,7 @@ function whenContainerReady(game, go, fn, attempts = 4) {
454
457
  * @returns PIXI 显示对象,失败返回 null
455
458
  */
456
459
  function resolveViewRef(game, go, ref) {
457
- var _a;
460
+ var _a, _b;
458
461
  if (!ref)
459
462
  return null;
460
463
  if ('entityName' in ref) {
@@ -469,15 +472,18 @@ function resolveViewRef(game, go, ref) {
469
472
  }
470
473
  }
471
474
  catch (_) { }
472
- return childContainer;
475
+ return wrapBorrowedEntityView(childContainer, child.name);
473
476
  }
474
477
  }
475
478
  if (ref.fallback)
476
479
  return resolveViewRef(game, go, ref.fallback);
477
480
  return null;
478
481
  }
482
+ if ('shape' in ref) {
483
+ return (_a = drawInlineShape(ref.shape)) !== null && _a !== void 0 ? _a : (ref.fallback ? resolveViewRef(game, go, ref.fallback) : null);
484
+ }
479
485
  if ('ui' in ref) {
480
- return (_a = drawInlineShape(ref.ui)) !== null && _a !== void 0 ? _a : (ref.fallback ? resolveViewRef(game, go, ref.fallback) : null);
486
+ return (_b = drawInlineShape(ref.ui)) !== null && _b !== void 0 ? _b : (ref.fallback ? resolveViewRef(game, go, ref.fallback) : null);
481
487
  }
482
488
  if ('texture' in ref) {
483
489
  const tex = resolveTexture(game, ref.texture);
@@ -506,9 +512,46 @@ function resolveViewRef(game, go, ref) {
506
512
  }
507
513
  return null;
508
514
  }
515
+ /**
516
+ * @pixi/ui ProgressBar 的非 nine-slice fillPaddings 只移动 fill.x/y,
517
+ * 不会自动把 fill view 缩成内层尺寸。DSL 常用的 inline color/shape
518
+ * 需要先扣除 padding,否则 fill 会向下或向右溢出,造成上下层偏差。
519
+ */
520
+ function normalizeProgressFillViewRef(ref, fillPaddings, fallbackSize) {
521
+ if (!ref)
522
+ return ref;
523
+ const paddings = normalizePaddings(fillPaddings);
524
+ if (paddings.top === 0 && paddings.right === 0 && paddings.bottom === 0 && paddings.left === 0) {
525
+ return ref;
526
+ }
527
+ const fallback = ref.fallback
528
+ ? normalizeProgressFillViewRef(ref.fallback, paddings, fallbackSize)
529
+ : undefined;
530
+ if ('color' in ref) {
531
+ const width = shrinkSize(ref.width, paddings.left + paddings.right);
532
+ const height = shrinkSize(ref.height, paddings.top + paddings.bottom);
533
+ return Object.assign(Object.assign(Object.assign({}, ref), { width,
534
+ height, radius: shrinkRadius(ref.radius, width, height) }), (fallback ? { fallback } : {}));
535
+ }
536
+ if ('shape' in ref) {
537
+ return Object.assign(Object.assign(Object.assign({}, ref), { shape: shrinkInlineShape(ref.shape, paddings, fallbackSize) }), (fallback ? { fallback } : {}));
538
+ }
539
+ if ('ui' in ref) {
540
+ return Object.assign(Object.assign(Object.assign({}, ref), { ui: shrinkInlineShape(ref.ui, paddings, fallbackSize) }), (fallback ? { fallback } : {}));
541
+ }
542
+ if (fallback)
543
+ return Object.assign(Object.assign({}, ref), { fallback });
544
+ return ref;
545
+ }
546
+ function wrapBorrowedEntityView(childContainer, childName) {
547
+ const wrapper = new pixi_js.Container();
548
+ wrapper.label = childName ? `${childName}:view-ref` : 'plugin-ui-view-ref';
549
+ wrapper.addChild(childContainer);
550
+ return wrapper;
551
+ }
509
552
  /** 把 ViewRef 解析为已存在的 Texture(用于 ProgressBar/Slider/Input 的 nineSlice 路径) */
510
553
  function resolveTexture(game, key) {
511
- var _a, _b;
554
+ var _a, _b, _c;
512
555
  // 1) Eva resource pool
513
556
  const resourceModule = (_a = game === null || game === void 0 ? void 0 : game.resource) !== null && _a !== void 0 ? _a : null;
514
557
  if ((_b = resourceModule === null || resourceModule === void 0 ? void 0 : resourceModule.instances) === null || _b === void 0 ? void 0 : _b[key]) {
@@ -520,45 +563,129 @@ function resolveTexture(game, key) {
520
563
  }
521
564
  // 2) global asset cache (Texture.from)
522
565
  try {
523
- return pixi_js.Texture.from(key);
566
+ return (_c = pixi_js.Texture.from(key)) !== null && _c !== void 0 ? _c : null;
524
567
  }
525
568
  catch (_) {
526
569
  return null;
527
570
  }
528
571
  }
529
572
  function drawInlineShape(shape) {
530
- var _a, _b, _c;
573
+ var _a, _b, _c, _d, _e;
531
574
  if (!shape || !shape.type)
532
575
  return null;
533
576
  const g = new pixi_js.Graphics();
534
577
  const { style } = shape;
535
- const w = (_a = style.width) !== null && _a !== void 0 ? _a : 0;
536
- const h = (_b = style.height) !== null && _b !== void 0 ? _b : 0;
537
- const r = (_c = style.radius) !== null && _c !== void 0 ? _c : 0;
578
+ const x = (_a = style.x) !== null && _a !== void 0 ? _a : 0;
579
+ const y = (_b = style.y) !== null && _b !== void 0 ? _b : 0;
580
+ const w = (_c = style.width) !== null && _c !== void 0 ? _c : 0;
581
+ const h = (_d = style.height) !== null && _d !== void 0 ? _d : 0;
582
+ const r = (_e = style.radius) !== null && _e !== void 0 ? _e : 0;
538
583
  switch (shape.type) {
539
584
  case 'rect':
540
- g.rect(0, 0, w, h);
585
+ drawRect(g, x, y, w, h);
541
586
  break;
542
587
  case 'roundedRect':
543
- g.roundRect(0, 0, w, h, r);
588
+ drawRoundedRect(g, x, y, w, h, r);
544
589
  break;
545
590
  case 'circle':
546
- g.circle(r, r, r);
591
+ drawCircle(g, x + r, y + r, r);
547
592
  break;
548
593
  case 'ellipse':
549
- g.ellipse(w / 2, h / 2, w / 2, h / 2);
594
+ drawEllipse(g, x + w / 2, y + h / 2, w / 2, h / 2);
550
595
  break;
551
596
  }
552
597
  if (style.fill !== undefined)
553
598
  g.fill(style.fill);
554
599
  if (style.stroke !== undefined && style.lineWidth !== undefined) {
555
- g.setStrokeStyle({ color: style.stroke, width: style.lineWidth });
556
- g.stroke();
600
+ g.stroke({ color: style.stroke, width: style.lineWidth });
601
+ }
602
+ else if (style.stroke !== undefined) {
603
+ g.stroke({ color: style.stroke, width: 1 });
557
604
  }
558
605
  if (style.alpha !== undefined)
559
606
  g.alpha = style.alpha;
607
+ try {
608
+ Object.defineProperty(g, 'clone', {
609
+ value: () => { var _a; return (_a = drawInlineShape(shape)) !== null && _a !== void 0 ? _a : new pixi_js.Graphics(); },
610
+ configurable: true,
611
+ });
612
+ }
613
+ catch (_) { }
560
614
  return g;
561
615
  }
616
+ function drawRect(g, x, y, width, height) {
617
+ const anyGraphics = g;
618
+ if (typeof anyGraphics.rect === 'function') {
619
+ anyGraphics.rect(x, y, width, height);
620
+ return;
621
+ }
622
+ anyGraphics.drawRect(x, y, width, height);
623
+ }
624
+ function drawRoundedRect(g, x, y, width, height, radius) {
625
+ const anyGraphics = g;
626
+ if (typeof anyGraphics.roundRect === 'function') {
627
+ anyGraphics.roundRect(x, y, width, height, radius);
628
+ return;
629
+ }
630
+ anyGraphics.drawRoundedRect(x, y, width, height, radius);
631
+ }
632
+ function drawCircle(g, x, y, radius) {
633
+ const anyGraphics = g;
634
+ if (typeof anyGraphics.circle === 'function') {
635
+ anyGraphics.circle(x, y, radius);
636
+ return;
637
+ }
638
+ anyGraphics.drawCircle(x, y, radius);
639
+ }
640
+ function drawEllipse(g, x, y, halfWidth, halfHeight) {
641
+ const anyGraphics = g;
642
+ if (typeof anyGraphics.ellipse === 'function') {
643
+ anyGraphics.ellipse(x, y, halfWidth, halfHeight);
644
+ return;
645
+ }
646
+ anyGraphics.drawEllipse(x, y, halfWidth, halfHeight);
647
+ }
648
+ function normalizePaddings(fillPaddings) {
649
+ return {
650
+ top: readPadding(fillPaddings === null || fillPaddings === void 0 ? void 0 : fillPaddings.top),
651
+ right: readPadding(fillPaddings === null || fillPaddings === void 0 ? void 0 : fillPaddings.right),
652
+ bottom: readPadding(fillPaddings === null || fillPaddings === void 0 ? void 0 : fillPaddings.bottom),
653
+ left: readPadding(fillPaddings === null || fillPaddings === void 0 ? void 0 : fillPaddings.left),
654
+ };
655
+ }
656
+ function readPadding(value) {
657
+ if (typeof value !== 'number' || !Number.isFinite(value))
658
+ return 0;
659
+ return Math.max(0, value);
660
+ }
661
+ function shrinkSize(value, inset) {
662
+ return Math.max(0, value - inset);
663
+ }
664
+ function shrinkOptionalSize(value, fallback, inset) {
665
+ if (typeof value === 'number')
666
+ return shrinkSize(value, inset);
667
+ if (typeof fallback === 'number')
668
+ return shrinkSize(fallback, inset);
669
+ return value;
670
+ }
671
+ function shrinkRadius(radius, width, height) {
672
+ if (typeof radius !== 'number' || !Number.isFinite(radius))
673
+ return radius;
674
+ const limits = [radius];
675
+ if (typeof width === 'number')
676
+ limits.push(width / 2);
677
+ if (typeof height === 'number')
678
+ limits.push(height / 2);
679
+ return Math.max(0, Math.min(...limits));
680
+ }
681
+ function shrinkInlineShape(shape, paddings, fallbackSize) {
682
+ var _a;
683
+ const style = (_a = shape.style) !== null && _a !== void 0 ? _a : {};
684
+ const width = shrinkOptionalSize(style.width, fallbackSize === null || fallbackSize === void 0 ? void 0 : fallbackSize.width, paddings.left + paddings.right);
685
+ const height = shrinkOptionalSize(style.height, fallbackSize === null || fallbackSize === void 0 ? void 0 : fallbackSize.height, paddings.top + paddings.bottom);
686
+ const radius = shrinkRadius(style.radius, width, height);
687
+ return Object.assign(Object.assign({}, shape), { style: Object.assign(Object.assign(Object.assign(Object.assign({}, style), (width !== undefined ? { width } : {})), (height !== undefined ? { height } : {})), (radius !== undefined ? { radius } : {})) });
688
+ }
562
689
  /**
563
690
  * 在 GameObject 的 transform.children 中查找指定名字的子 entity。
564
691
  * 不递归 — plugin-ui 的视觉子项语义只允许直接子节点。
@@ -609,12 +736,20 @@ class PixiUiComponent extends eva_js.Component {
609
736
  /** runtime 计数,供 spec / debug 验证(toggleCount / pressCount / hoverCount / ...)*/
610
737
  this.toggleCount = 0;
611
738
  this.pressCount = 0;
739
+ this.downCount = 0;
740
+ this.upCount = 0;
612
741
  this.hoverCount = 0;
742
+ this.outCount = 0;
743
+ this.upOutCount = 0;
613
744
  this.changeCount = 0;
614
745
  this.updateCount = 0;
615
746
  this.selectCount = 0;
747
+ this.lastSignal = 'idle';
748
+ this.visualState = 'default';
616
749
  /** Input 私有 focused */
617
750
  this.focused = false;
751
+ /** DSL/constructor 中显式传入过的字段,用于区分 metadata default 与用户配置。 */
752
+ this.__evaExplicitFields = new Set();
618
753
  }
619
754
  init(p) {
620
755
  if (p)
@@ -634,6 +769,7 @@ class PixiUiComponent extends eva_js.Component {
634
769
  const v = p[name];
635
770
  if (v === undefined)
636
771
  continue;
772
+ this.__evaExplicitFields.add(name);
637
773
  switch (spec.kind) {
638
774
  case 'scalar':
639
775
  this[name] = v;
@@ -754,6 +890,114 @@ function resolveViewsBySchema(game, go, component, schema) {
754
890
  }
755
891
  }
756
892
 
893
+ function readTransformRenderSize(go, options = {}) {
894
+ var _a;
895
+ const size = (_a = go === null || go === void 0 ? void 0 : go.transform) === null || _a === void 0 ? void 0 : _a.size;
896
+ if (!size)
897
+ return null;
898
+ const width = normalizeSizeValue(size.width, options.allowZero);
899
+ const height = normalizeSizeValue(size.height, options.allowZero);
900
+ if (width === undefined && height === undefined)
901
+ return null;
902
+ return { width, height };
903
+ }
904
+ function hasExplicitRenderSize(component) {
905
+ if (!component)
906
+ return false;
907
+ const explicitFields = component.__evaExplicitFields;
908
+ if (explicitFields && typeof explicitFields.has === 'function') {
909
+ return explicitFields.has('width') || explicitFields.has('height');
910
+ }
911
+ return component.width !== undefined || component.height !== undefined;
912
+ }
913
+ function applyTransformSizeToInstance(def, instance, component, go, source) {
914
+ const size = readTransformRenderSize(go, { allowZero: source === 'transform-change' });
915
+ if (!size)
916
+ return false;
917
+ const context = {
918
+ componentName: def.name,
919
+ component,
920
+ gameObject: go,
921
+ source,
922
+ };
923
+ if (def.applySize)
924
+ def.applySize(instance, size, component !== null && component !== void 0 ? component : {}, context);
925
+ else
926
+ applyRuntimeSize(instance, size);
927
+ return true;
928
+ }
929
+ function applyRuntimeSize(instance, size) {
930
+ if (!instance || !size)
931
+ return;
932
+ const width = normalizeSizeValue(size.width, true);
933
+ const height = normalizeSizeValue(size.height, true);
934
+ if (width === undefined && height === undefined)
935
+ return;
936
+ const nextWidth = width !== null && width !== void 0 ? width : getCurrentSize(instance, 'width');
937
+ const nextHeight = height !== null && height !== void 0 ? height : getCurrentSize(instance, 'height');
938
+ let applied = false;
939
+ if (typeof instance.setSize === 'function' && nextWidth !== undefined && nextHeight !== undefined) {
940
+ try {
941
+ instance.setSize(nextWidth, nextHeight);
942
+ applied = true;
943
+ }
944
+ catch (_) {
945
+ applied = false;
946
+ }
947
+ }
948
+ if (!applied) {
949
+ if (width !== undefined)
950
+ instance.width = width;
951
+ if (height !== undefined)
952
+ instance.height = height;
953
+ }
954
+ relayoutRuntimeInstance(instance);
955
+ }
956
+ function applyListLayoutSize(instance, size) {
957
+ const width = normalizeSizeValue(size.width, true);
958
+ const height = normalizeSizeValue(size.height, true);
959
+ if (width !== undefined) {
960
+ try {
961
+ instance.maxWidth = width;
962
+ }
963
+ catch (_) { }
964
+ }
965
+ if (height !== undefined) {
966
+ try {
967
+ instance.maxHeight = height;
968
+ }
969
+ catch (_) { }
970
+ }
971
+ relayoutRuntimeInstance(instance);
972
+ }
973
+ function relayoutRuntimeInstance(instance) {
974
+ var _a, _b, _c, _d;
975
+ try {
976
+ (_b = (_a = instance === null || instance === void 0 ? void 0 : instance.list) === null || _a === void 0 ? void 0 : _a.arrangeChildren) === null || _b === void 0 ? void 0 : _b.call(_a);
977
+ }
978
+ catch (_) { }
979
+ try {
980
+ (_c = instance === null || instance === void 0 ? void 0 : instance.arrangeChildren) === null || _c === void 0 ? void 0 : _c.call(instance);
981
+ }
982
+ catch (_) { }
983
+ try {
984
+ (_d = instance === null || instance === void 0 ? void 0 : instance.resize) === null || _d === void 0 ? void 0 : _d.call(instance, true);
985
+ }
986
+ catch (_) { }
987
+ }
988
+ function normalizeSizeValue(value, allowZero = false) {
989
+ const n = Number(value);
990
+ if (!Number.isFinite(n))
991
+ return undefined;
992
+ if (allowZero ? n < 0 : n <= 0)
993
+ return undefined;
994
+ return n;
995
+ }
996
+ function getCurrentSize(instance, key) {
997
+ const n = Number(instance === null || instance === void 0 ? void 0 : instance[key]);
998
+ return Number.isFinite(n) && n >= 0 ? n : undefined;
999
+ }
1000
+
757
1001
  /**
758
1002
  * @pixi/ui v2.x 包装层 — 14 个 ECS Component 由 metadata 驱动生成。
759
1003
  *
@@ -801,8 +1045,42 @@ const BUTTON_DEF = {
801
1045
  optionsBuilder: (_c, v) => [v.single],
802
1046
  postCreate: (inst, c) => { inst.enabled = c.enabled; },
803
1047
  signalMap: (c) => ({
804
- press: () => { c.pressCount += 1; return {}; },
805
- down: true, up: true, hover: true,
1048
+ press: () => {
1049
+ c.pressCount += 1;
1050
+ c.lastSignal = 'press';
1051
+ c.visualState = 'default';
1052
+ return { pressCount: c.pressCount, lastSignal: c.lastSignal, visualState: c.visualState };
1053
+ },
1054
+ down: () => {
1055
+ c.downCount += 1;
1056
+ c.lastSignal = 'down';
1057
+ c.visualState = 'pressed';
1058
+ return { downCount: c.downCount, lastSignal: c.lastSignal, visualState: c.visualState };
1059
+ },
1060
+ up: () => {
1061
+ c.upCount += 1;
1062
+ c.lastSignal = 'up';
1063
+ c.visualState = 'default';
1064
+ return { upCount: c.upCount, lastSignal: c.lastSignal, visualState: c.visualState };
1065
+ },
1066
+ hover: () => {
1067
+ c.hoverCount += 1;
1068
+ c.lastSignal = 'hover';
1069
+ c.visualState = 'hover';
1070
+ return { hoverCount: c.hoverCount, lastSignal: c.lastSignal, visualState: c.visualState };
1071
+ },
1072
+ out: () => {
1073
+ c.outCount += 1;
1074
+ c.lastSignal = 'out';
1075
+ c.visualState = 'default';
1076
+ return { outCount: c.outCount, lastSignal: c.lastSignal, visualState: c.visualState };
1077
+ },
1078
+ upOut: () => {
1079
+ c.upOutCount += 1;
1080
+ c.lastSignal = 'upOut';
1081
+ c.visualState = 'default';
1082
+ return { upOutCount: c.upOutCount, lastSignal: c.lastSignal, visualState: c.visualState };
1083
+ },
806
1084
  }),
807
1085
  syncOnChange: (inst, c) => { inst.enabled = c.enabled; },
808
1086
  };
@@ -820,10 +1098,28 @@ const FANCY_BUTTON_DEF = {
820
1098
  views: { kind: 'shallowMerge', default: {}, inspector: { name: 'views', type: 'object', isFolder: true, children: [
821
1099
  { name: 'default', type: 'object' }, { name: 'hover', type: 'object' },
822
1100
  { name: 'pressed', type: 'object' }, { name: 'disabled', type: 'object' },
1101
+ { name: 'icon', type: 'object' },
823
1102
  ] } },
824
1103
  offset: { kind: 'shallowMerge', default: {} },
825
1104
  textOffset: { kind: 'shallowMerge', default: {} },
1105
+ iconOffset: { kind: 'shallowMerge', default: {} },
826
1106
  nineSliceSprite: { kind: 'opaque' },
1107
+ textStyle: { kind: 'shallowMerge', default: {} },
1108
+ textClass: { kind: 'scalar', default: 'text' },
1109
+ bitmapFontName: { kind: 'scalar', default: 'TitleFont' },
1110
+ defaultTextScale: { kind: 'opaque' },
1111
+ defaultIconScale: { kind: 'opaque' },
1112
+ defaultTextAnchor: { kind: 'opaque' },
1113
+ defaultIconAnchor: { kind: 'opaque' },
1114
+ anchor: { kind: 'scalar' },
1115
+ anchorX: { kind: 'scalar' },
1116
+ anchorY: { kind: 'scalar' },
1117
+ scale: { kind: 'scalar' },
1118
+ animations: { kind: 'opaque' },
1119
+ contentFittingMode: { kind: 'scalar' },
1120
+ ignoreRefitting: { kind: 'scalar' },
1121
+ width: { kind: 'scalar', inspector: { name: 'width', type: 'number' } },
1122
+ height: { kind: 'scalar', inspector: { name: 'height', type: 'number' } },
827
1123
  },
828
1124
  views: {
829
1125
  kind: 'object', folder: 'views',
@@ -832,28 +1128,43 @@ const FANCY_BUTTON_DEF = {
832
1128
  { name: 'hover', required: false },
833
1129
  { name: 'pressed', required: false },
834
1130
  { name: 'disabled', required: false },
1131
+ { name: 'icon', required: false },
835
1132
  ],
836
1133
  },
837
1134
  optionsBuilder: (c, v) => {
838
- var _a, _b, _d, _e;
1135
+ var _a, _b, _d, _e, _f;
839
1136
  // FancyButton 内部 updateView 不接受 null;只把已 resolve 的 view 字段传过去
840
1137
  const opts = {
841
- text: c.text, padding: c.padding,
842
- offset: c.offset, textOffset: c.textOffset,
1138
+ text: makeFancyButtonText(c), padding: c.padding,
1139
+ offset: c.offset, textOffset: c.textOffset, iconOffset: c.iconOffset,
843
1140
  nineSliceSprite: c.nineSliceSprite,
1141
+ defaultTextScale: c.defaultTextScale,
1142
+ defaultIconScale: c.defaultIconScale,
1143
+ defaultTextAnchor: c.defaultTextAnchor,
1144
+ defaultIconAnchor: c.defaultIconAnchor,
1145
+ anchor: c.anchor, anchorX: c.anchorX, anchorY: c.anchorY,
1146
+ scale: c.scale, animations: c.animations,
1147
+ contentFittingMode: c.contentFittingMode,
1148
+ ignoreRefitting: c.ignoreRefitting,
844
1149
  };
845
1150
  if ((_a = v.object) === null || _a === void 0 ? void 0 : _a.default)
846
- opts.defaultView = v.object.default;
1151
+ opts.defaultView = getFancyButtonView(c, 'default', v.object.default);
847
1152
  if ((_b = v.object) === null || _b === void 0 ? void 0 : _b.hover)
848
- opts.hoverView = v.object.hover;
1153
+ opts.hoverView = getFancyButtonView(c, 'hover', v.object.hover);
849
1154
  if ((_d = v.object) === null || _d === void 0 ? void 0 : _d.pressed)
850
- opts.pressedView = v.object.pressed;
1155
+ opts.pressedView = getFancyButtonView(c, 'pressed', v.object.pressed);
851
1156
  if ((_e = v.object) === null || _e === void 0 ? void 0 : _e.disabled)
852
- opts.disabledView = v.object.disabled;
1157
+ opts.disabledView = getFancyButtonView(c, 'disabled', v.object.disabled);
1158
+ if ((_f = v.object) === null || _f === void 0 ? void 0 : _f.icon)
1159
+ opts.icon = v.object.icon;
853
1160
  return opts;
854
1161
  },
855
1162
  postCreate: (inst, c) => {
856
1163
  inst.enabled = c.enabled;
1164
+ if (c.state && typeof inst.setState === 'function')
1165
+ inst.setState(c.state, true);
1166
+ applyFancyButtonAnchor(inst, c);
1167
+ applyOptionalSize(inst, c);
857
1168
  if (c.selected)
858
1169
  applySelectedTint(inst, c);
859
1170
  },
@@ -868,9 +1179,84 @@ const FANCY_BUTTON_DEF = {
868
1179
  inst.text = c.text;
869
1180
  if (c.padding !== undefined && inst.padding !== c.padding)
870
1181
  inst.padding = c.padding;
1182
+ if (c.textOffset !== undefined)
1183
+ inst.textOffset = c.textOffset;
1184
+ if (c.iconOffset !== undefined)
1185
+ inst.iconOffset = c.iconOffset;
1186
+ if (c.defaultTextScale !== undefined)
1187
+ inst.defaultTextScale = c.defaultTextScale;
1188
+ if (c.defaultIconScale !== undefined)
1189
+ inst.defaultIconScale = c.defaultIconScale;
1190
+ if (c.defaultTextAnchor !== undefined)
1191
+ inst.defaultTextAnchor = c.defaultTextAnchor;
1192
+ if (c.defaultIconAnchor !== undefined)
1193
+ inst.defaultIconAnchor = c.defaultIconAnchor;
1194
+ if (c.contentFittingMode !== undefined)
1195
+ inst.contentFittingMode = c.contentFittingMode;
1196
+ if (c.ignoreRefitting !== undefined && inst.options)
1197
+ inst.options.ignoreRefitting = c.ignoreRefitting;
1198
+ if (c.state && typeof inst.setState === 'function')
1199
+ inst.setState(c.state, true);
1200
+ applyFancyButtonAnchor(inst, c);
1201
+ applyOptionalSize(inst, c);
871
1202
  applySelectedTint(inst, c);
872
1203
  },
873
1204
  };
1205
+ function applyFancyButtonAnchor(inst, c) {
1206
+ var _a, _b, _d, _e, _f, _g, _h;
1207
+ const hasAnchor = c.anchor !== undefined || c.anchorX !== undefined || c.anchorY !== undefined;
1208
+ if (!hasAnchor || !((_a = inst === null || inst === void 0 ? void 0 : inst.anchor) === null || _a === void 0 ? void 0 : _a.set))
1209
+ return;
1210
+ const x = (_e = (_d = (_b = c.anchorX) !== null && _b !== void 0 ? _b : c.anchor) !== null && _d !== void 0 ? _d : inst.anchor.x) !== null && _e !== void 0 ? _e : 0;
1211
+ const y = (_h = (_g = (_f = c.anchorY) !== null && _f !== void 0 ? _f : c.anchor) !== null && _g !== void 0 ? _g : inst.anchor.y) !== null && _h !== void 0 ? _h : 0;
1212
+ try {
1213
+ inst.anchor.set(x, y);
1214
+ }
1215
+ catch (_) { }
1216
+ }
1217
+ function makeFancyButtonText(c) {
1218
+ var _a, _b, _d;
1219
+ if (c.text === undefined)
1220
+ return undefined;
1221
+ const text = String(c.text);
1222
+ if (c.textClass === 'html') {
1223
+ return new pixi_js.HTMLText({ text, style: c.textStyle });
1224
+ }
1225
+ if (c.textClass === 'bitmap') {
1226
+ const fontFamily = (_a = c.bitmapFontName) !== null && _a !== void 0 ? _a : 'TitleFont';
1227
+ ensureBitmapFont(fontFamily, c.textStyle);
1228
+ return new pixi_js.BitmapText({
1229
+ text,
1230
+ style: {
1231
+ fontFamily,
1232
+ fontSize: (_d = (_b = c.textStyle) === null || _b === void 0 ? void 0 : _b.fontSize) !== null && _d !== void 0 ? _d : 40,
1233
+ },
1234
+ });
1235
+ }
1236
+ if (c.textStyle && Object.keys(c.textStyle).length > 0) {
1237
+ return new pixi_js.Text({ text, style: c.textStyle });
1238
+ }
1239
+ return c.text;
1240
+ }
1241
+ const installedBitmapFonts = new Set();
1242
+ function ensureBitmapFont(name, style) {
1243
+ if (installedBitmapFonts.has(name))
1244
+ return;
1245
+ try {
1246
+ pixi_js.BitmapFontManager.install({ name, style: (style !== null && style !== void 0 ? style : {}) });
1247
+ }
1248
+ catch (_) {
1249
+ // Reinstalling an existing font can throw in Pixi; rendering can still use the current font.
1250
+ }
1251
+ installedBitmapFonts.add(name);
1252
+ }
1253
+ function getFancyButtonView(c, key, resolved) {
1254
+ var _a;
1255
+ const ref = (_a = c.views) === null || _a === void 0 ? void 0 : _a[key];
1256
+ if (c.nineSliceSprite && ref && 'texture' in ref)
1257
+ return getTextureView(ref.texture);
1258
+ return resolved;
1259
+ }
874
1260
  function applySelectedTint(inst, c) {
875
1261
  try {
876
1262
  const dv = inst.defaultView;
@@ -879,6 +1265,22 @@ function applySelectedTint(inst, c) {
879
1265
  }
880
1266
  catch (_) { }
881
1267
  }
1268
+ function syncCheckBoxTextStyle(inst, c) {
1269
+ var _a, _b, _d;
1270
+ const style = inst.style;
1271
+ if (!style || (!c.textStyle && !c.textOffset))
1272
+ return;
1273
+ const nextStyle = Object.assign(Object.assign({}, style), { text: (_a = c.textStyle) !== null && _a !== void 0 ? _a : style.text, textOffset: (_b = c.textOffset) !== null && _b !== void 0 ? _b : style.textOffset });
1274
+ // @pixi/ui CheckBox.style rebuilds checked/unchecked views. If RadioGroup is
1275
+ // listening, that rebuild can emit onChange while only one view exists.
1276
+ inst._style = nextStyle;
1277
+ if (inst.labelText && c.textStyle)
1278
+ inst.labelText.style = c.textStyle;
1279
+ try {
1280
+ (_d = inst.alignText) === null || _d === void 0 ? void 0 : _d.call(inst);
1281
+ }
1282
+ catch (_) { }
1283
+ }
882
1284
  const CHECKBOX_DEF = {
883
1285
  name: 'CheckBox',
884
1286
  signalPrefix: 'checkbox',
@@ -891,6 +1293,8 @@ const CHECKBOX_DEF = {
891
1293
  views: { kind: 'shallowMerge', default: {}, inspector: { name: 'views', type: 'object', isFolder: true, children: [
892
1294
  { name: 'checked', type: 'object' }, { name: 'unchecked', type: 'object' },
893
1295
  ] } },
1296
+ textStyle: { kind: 'shallowMerge', default: { fill: 0xffffff } },
1297
+ textOffset: { kind: 'shallowMerge', default: {} },
894
1298
  disabledStyle: { kind: 'shallowMerge', default: { alpha: 0.4, scale: 1 } },
895
1299
  },
896
1300
  views: {
@@ -901,7 +1305,7 @@ const CHECKBOX_DEF = {
901
1305
  ],
902
1306
  },
903
1307
  optionsBuilder: (c, v) => ({
904
- style: { checked: v.object.checked, unchecked: v.object.unchecked },
1308
+ style: { checked: v.object.checked, unchecked: v.object.unchecked, text: c.textStyle, textOffset: c.textOffset },
905
1309
  text: c.text, checked: c.checked,
906
1310
  }),
907
1311
  signalMap: (c) => ({
@@ -910,6 +1314,9 @@ const CHECKBOX_DEF = {
910
1314
  syncOnChange: (inst, c) => {
911
1315
  if (inst.checked !== c.checked)
912
1316
  inst.checked = c.checked;
1317
+ if (c.text !== undefined && inst.text !== c.text)
1318
+ inst.text = c.text;
1319
+ syncCheckBoxTextStyle(inst, c);
913
1320
  },
914
1321
  };
915
1322
  const SWITCHER_DEF = {
@@ -936,6 +1343,8 @@ const SWITCHER_DEF = {
936
1343
  syncOnChange: (inst, c) => {
937
1344
  if (inst.active !== c.active)
938
1345
  inst.active = c.active;
1346
+ if (c.triggerEvent !== undefined)
1347
+ inst.triggerEvents = c.triggerEvent;
939
1348
  },
940
1349
  };
941
1350
  const SLIDER_DEF = {
@@ -951,6 +1360,12 @@ const SLIDER_DEF = {
951
1360
  orientation: { kind: 'scalar', default: 'horizontal', inspector: { name: 'orientation', type: 'string' } },
952
1361
  showValue: { kind: 'scalar', default: false, inspector: { name: 'showValue', type: 'boolean' } },
953
1362
  views: { kind: 'shallowMerge', default: {} },
1363
+ nineSliceSprite: { kind: 'opaque' },
1364
+ fillPaddings: { kind: 'shallowMerge', default: {} },
1365
+ valueTextStyle: { kind: 'shallowMerge', default: { fill: 0xffffff } },
1366
+ valueTextOffset: { kind: 'shallowMerge', default: {} },
1367
+ width: { kind: 'scalar', inspector: { name: 'width', type: 'number' } },
1368
+ height: { kind: 'scalar', inspector: { name: 'height', type: 'number' } },
954
1369
  bindToStore: BIND_STORE,
955
1370
  },
956
1371
  views: {
@@ -962,12 +1377,20 @@ const SLIDER_DEF = {
962
1377
  ],
963
1378
  },
964
1379
  optionsBuilder: (c, v) => {
965
- centerThumbPivot(v.object.thumb);
1380
+ var _a, _b, _d;
1381
+ const bg = getSliderView((_a = c.views) === null || _a === void 0 ? void 0 : _a.bg, v.object.bg);
1382
+ const fill = getSliderView((_b = c.views) === null || _b === void 0 ? void 0 : _b.fill, v.object.fill);
1383
+ const thumb = getSliderView((_d = c.views) === null || _d === void 0 ? void 0 : _d.thumb, v.object.thumb);
966
1384
  return {
967
- bg: v.object.bg, fill: v.object.fill, slider: v.object.thumb,
1385
+ bg, fill, slider: thumb,
968
1386
  min: c.min, max: c.max, step: c.step, value: c.value, showValue: c.showValue,
1387
+ fillPaddings: c.fillPaddings,
1388
+ nineSliceSprite: c.nineSliceSprite,
1389
+ valueTextStyle: c.valueTextStyle,
1390
+ valueTextOffset: c.valueTextOffset,
969
1391
  };
970
1392
  },
1393
+ postCreate: (inst, c) => applyOptionalSize(inst, c),
971
1394
  signalMap: (c) => ({
972
1395
  update: (vv) => { c.value = vv; c.updateCount += 1; return { value: vv }; },
973
1396
  change: (vv) => { c.value = vv; c.changeCount += 1; return { value: vv }; },
@@ -975,37 +1398,9 @@ const SLIDER_DEF = {
975
1398
  syncOnChange: (inst, c) => {
976
1399
  if (inst.value !== c.value)
977
1400
  inst.value = c.value;
1401
+ applyOptionalSize(inst, c);
978
1402
  },
979
1403
  };
980
- /**
981
- * @pixi/ui Slider 的 update 逻辑:
982
- * slider.x = (bg.width/100 * progress) - (slider.width / 2) // x 已居中
983
- * slider.y = bg.height / 2 // y 未居中(bug)
984
- *
985
- * 因 y 维度 @pixi/ui 假设 thumb anchor / pivot 在中心(对 Sprite 自动 anchor.set(0.5),
986
- * 但 Graphics 没 anchor),Graphics 渲染时左上角对齐 bg 中线,thumb 中心落到中线下方。
987
- *
988
- * 修法:只设 pivot.y = h/2 让 thumb 沿 y 居中。pivot.x 保持 0(x 在 update
989
- * 里已用 -width/2 居中过,再设 pivot.x 会双倍偏移)。
990
- */
991
- function centerThumbPivot(thumb) {
992
- var _a, _b, _d, _e;
993
- if (!thumb)
994
- return;
995
- if (thumb.anchor)
996
- return; // Sprite — @pixi/ui 自己 anchor.set(0.5)
997
- let h = 0;
998
- try {
999
- const b = (_a = thumb.getBounds) === null || _a === void 0 ? void 0 : _a.call(thumb);
1000
- h = (_d = (_b = b === null || b === void 0 ? void 0 : b.height) !== null && _b !== void 0 ? _b : thumb.height) !== null && _d !== void 0 ? _d : 0;
1001
- }
1002
- catch (_) {
1003
- h = (_e = thumb.height) !== null && _e !== void 0 ? _e : 0;
1004
- }
1005
- if (h > 0 && thumb.pivot) {
1006
- thumb.pivot.set(0, h / 2);
1007
- }
1008
- }
1009
1404
  const DOUBLE_SLIDER_DEF = {
1010
1405
  name: 'DoubleSlider',
1011
1406
  signalPrefix: 'doubleslider',
@@ -1019,6 +1414,12 @@ const DOUBLE_SLIDER_DEF = {
1019
1414
  step: { kind: 'scalar', default: 1 },
1020
1415
  showValue: { kind: 'scalar', default: false, inspector: { name: 'showValue', type: 'boolean' } },
1021
1416
  views: { kind: 'shallowMerge', default: {} },
1417
+ nineSliceSprite: { kind: 'opaque' },
1418
+ fillPaddings: { kind: 'shallowMerge', default: {} },
1419
+ valueTextStyle: { kind: 'shallowMerge', default: { fill: 0xffffff } },
1420
+ valueTextOffset: { kind: 'shallowMerge', default: {} },
1421
+ width: { kind: 'scalar', inspector: { name: 'width', type: 'number' } },
1422
+ height: { kind: 'scalar', inspector: { name: 'height', type: 'number' } },
1022
1423
  bindToStore1: { kind: 'scalar' },
1023
1424
  bindToStore2: { kind: 'scalar' },
1024
1425
  },
@@ -1030,14 +1431,22 @@ const DOUBLE_SLIDER_DEF = {
1030
1431
  ],
1031
1432
  },
1032
1433
  optionsBuilder: (c, v) => {
1033
- centerThumbPivot(v.object.slider1);
1034
- centerThumbPivot(v.object.slider2);
1434
+ var _a, _b, _d, _e;
1435
+ const bg = getSliderView((_a = c.views) === null || _a === void 0 ? void 0 : _a.bg, v.object.bg);
1436
+ const fill = getSliderView((_b = c.views) === null || _b === void 0 ? void 0 : _b.fill, v.object.fill);
1437
+ const slider1 = getSliderView((_d = c.views) === null || _d === void 0 ? void 0 : _d.slider1, v.object.slider1);
1438
+ const slider2 = getSliderView((_e = c.views) === null || _e === void 0 ? void 0 : _e.slider2, v.object.slider2);
1035
1439
  return {
1036
- bg: v.object.bg, fill: v.object.fill,
1037
- slider1: v.object.slider1, slider2: v.object.slider2,
1038
- min: c.min, max: c.max, value1: c.value1, value2: c.value2, showValue: c.showValue,
1440
+ bg, fill,
1441
+ slider1, slider2,
1442
+ min: c.min, max: c.max, step: c.step, value1: c.value1, value2: c.value2, showValue: c.showValue,
1443
+ fillPaddings: c.fillPaddings,
1444
+ nineSliceSprite: c.nineSliceSprite,
1445
+ valueTextStyle: c.valueTextStyle,
1446
+ valueTextOffset: c.valueTextOffset,
1039
1447
  };
1040
1448
  },
1449
+ postCreate: (inst, c) => applyOptionalSize(inst, c),
1041
1450
  signalMap: (c) => ({
1042
1451
  update: (v1, v2) => { c.value1 = v1; c.value2 = v2; c.updateCount += 1; return { value1: v1, value2: v2 }; },
1043
1452
  change: (v1, v2) => { c.value1 = v1; c.value2 = v2; c.changeCount += 1; return { value1: v1, value2: v2 }; },
@@ -1047,6 +1456,7 @@ const DOUBLE_SLIDER_DEF = {
1047
1456
  inst.value1 = c.value1;
1048
1457
  if (inst.value2 !== c.value2)
1049
1458
  inst.value2 = c.value2;
1459
+ applyOptionalSize(inst, c);
1050
1460
  },
1051
1461
  };
1052
1462
  const PROGRESS_BAR_DEF = {
@@ -1060,6 +1470,8 @@ const PROGRESS_BAR_DEF = {
1060
1470
  fillView: { kind: 'opaque' },
1061
1471
  nineSliceSprite: { kind: 'opaque' },
1062
1472
  fillPaddings: { kind: 'shallowMerge', default: {} },
1473
+ width: { kind: 'scalar', inspector: { name: 'width', type: 'number' } },
1474
+ height: { kind: 'scalar', inspector: { name: 'height', type: 'number' } },
1063
1475
  bindToStore: BIND_STORE,
1064
1476
  },
1065
1477
  views: {
@@ -1070,17 +1482,54 @@ const PROGRESS_BAR_DEF = {
1070
1482
  // 这里用 inline resolution(在 system.ts handleGeneric 里有 fast path 处理 views=undefined 的情形,
1071
1483
  // optionsBuilder 接受 raw component 自己 resolve)
1072
1484
  optionsBuilder: (c, _v) => ({
1073
- bg: c.__resolved_bg, fill: c.__resolved_fill,
1485
+ bg: c.__resolved_bg_view, fill: c.__resolved_fill_view,
1074
1486
  fillPaddings: c.fillPaddings,
1487
+ nineSliceSprite: c.nineSliceSprite,
1075
1488
  progress: computeProgressPct(c),
1076
1489
  }),
1490
+ postCreate: (inst, c) => applyOptionalSize(inst, c),
1077
1491
  syncOnChange: (inst, c) => {
1078
1492
  const pct = computeProgressPct(c);
1079
1493
  if (inst.progress !== pct)
1080
1494
  inst.progress = pct;
1495
+ applyOptionalSize(inst, c);
1081
1496
  },
1082
1497
  mixin: { getProgressPct: getProgressPctMixin },
1083
1498
  };
1499
+ function getSliderView(ref, resolved) {
1500
+ if (ref && 'texture' in ref) {
1501
+ return getTextureView(ref.texture);
1502
+ }
1503
+ return resolved;
1504
+ }
1505
+ function getProgressView(ref, resolved, nineSliceSprite) {
1506
+ if (nineSliceSprite && ref && 'texture' in ref) {
1507
+ return getTextureView(ref.texture);
1508
+ }
1509
+ return resolved;
1510
+ }
1511
+ function getTextureView(textureKey) {
1512
+ var _a;
1513
+ return (_a = resolveTexture(undefined, textureKey)) !== null && _a !== void 0 ? _a : textureKey;
1514
+ }
1515
+ function applyOptionalSize(inst, c) {
1516
+ var _a, _b;
1517
+ if (c.width === undefined && c.height === undefined)
1518
+ return;
1519
+ const width = (_a = c.width) !== null && _a !== void 0 ? _a : inst.width;
1520
+ const height = (_b = c.height) !== null && _b !== void 0 ? _b : inst.height;
1521
+ if (typeof inst.setSize === 'function') {
1522
+ try {
1523
+ inst.setSize(width, height);
1524
+ return;
1525
+ }
1526
+ catch (_) { }
1527
+ }
1528
+ if (c.width !== undefined)
1529
+ inst.width = c.width;
1530
+ if (c.height !== undefined)
1531
+ inst.height = c.height;
1532
+ }
1084
1533
  function computeProgressPct(c) {
1085
1534
  const [min, max] = c.valueRange;
1086
1535
  if (max <= min)
@@ -1102,21 +1551,36 @@ const CIRCULAR_PROGRESS_BAR_DEF = {
1102
1551
  fillColor: { kind: 'scalar', default: '#22c55e', inspector: { name: 'fillColor', type: 'color' } },
1103
1552
  backgroundAlpha: { kind: 'scalar', default: 1, inspector: { name: 'backgroundAlpha', type: 'number', step: 0.05 } },
1104
1553
  fillAlpha: { kind: 'scalar', default: 1, inspector: { name: 'fillAlpha', type: 'number', step: 0.05 } },
1554
+ cap: { kind: 'scalar', inspector: { name: 'cap', type: 'string' } },
1555
+ rotation: { kind: 'scalar', default: 0 },
1556
+ offset: { kind: 'shallowMerge', default: {} },
1105
1557
  bindToStore: BIND_STORE,
1106
1558
  },
1107
1559
  optionsBuilder: (c) => ({
1108
1560
  radius: c.radius, lineWidth: c.lineWidth,
1109
1561
  backgroundColor: c.backgroundColor, fillColor: c.fillColor,
1110
1562
  backgroundAlpha: c.backgroundAlpha, fillAlpha: c.fillAlpha,
1563
+ cap: c.cap,
1111
1564
  value: computeProgressPct(c),
1112
1565
  }),
1566
+ postCreate: (inst, c) => applyCircularProgressTransform(inst, c),
1113
1567
  syncOnChange: (inst, c) => {
1114
1568
  const pct = computeProgressPct(c);
1115
1569
  if (inst.progress !== pct)
1116
1570
  inst.progress = pct;
1571
+ applyCircularProgressTransform(inst, c);
1117
1572
  },
1118
1573
  mixin: { getProgressPct: getProgressPctMixin },
1119
1574
  };
1575
+ function applyCircularProgressTransform(inst, c) {
1576
+ var _a, _b;
1577
+ if (c.rotation !== undefined)
1578
+ inst.rotation = c.rotation;
1579
+ if (c.offset) {
1580
+ inst.x = (_a = c.offset.x) !== null && _a !== void 0 ? _a : 0;
1581
+ inst.y = (_b = c.offset.y) !== null && _b !== void 0 ? _b : 0;
1582
+ }
1583
+ }
1120
1584
  const INPUT_DEF = {
1121
1585
  name: 'Input',
1122
1586
  signalPrefix: 'input',
@@ -1134,15 +1598,18 @@ const INPUT_DEF = {
1134
1598
  nineSliceSprite: { kind: 'opaque' },
1135
1599
  cleanOnFocus: { kind: 'scalar', default: false, inspector: { name: 'cleanOnFocus', type: 'boolean' } },
1136
1600
  addMask: { kind: 'scalar', default: false, inspector: { name: 'addMask', type: 'boolean' } },
1601
+ width: { kind: 'scalar', inspector: { name: 'width', type: 'number' } },
1602
+ height: { kind: 'scalar', inspector: { name: 'height', type: 'number' } },
1137
1603
  bindToStore: BIND_STORE,
1138
1604
  },
1139
1605
  views: { kind: 'single', key: 'bgView', required: true },
1140
1606
  optionsBuilder: (c, v) => ({
1141
- bg: v.single, textStyle: c.textStyle,
1607
+ bg: getProgressView(c.bgView, v.single, c.nineSliceSprite), textStyle: c.textStyle,
1142
1608
  placeholder: c.placeholder, value: c.value, maxLength: c.maxLength, secure: c.secure,
1143
1609
  align: c.align, padding: c.padding,
1144
1610
  cleanOnFocus: c.cleanOnFocus, nineSliceSprite: c.nineSliceSprite, addMask: c.addMask,
1145
1611
  }),
1612
+ postCreate: (inst, c) => { inst.enabled = c.enabled; applyOptionalSize(inst, c); },
1146
1613
  signalMap: (c) => ({
1147
1614
  change: (text) => { c.value = text; c.changeCount += 1; return { value: text }; },
1148
1615
  enter: (text) => ({ value: text }),
@@ -1150,6 +1617,9 @@ const INPUT_DEF = {
1150
1617
  syncOnChange: (inst, c) => {
1151
1618
  if (inst.value !== c.value)
1152
1619
  inst.value = c.value;
1620
+ if (inst.enabled !== c.enabled)
1621
+ inst.enabled = c.enabled;
1622
+ applyOptionalSize(inst, c);
1153
1623
  },
1154
1624
  };
1155
1625
  const LIST_DEF = {
@@ -1171,18 +1641,25 @@ const LIST_DEF = {
1171
1641
  itemsChildName: { kind: 'scalar', default: 'items' },
1172
1642
  },
1173
1643
  // List 不走 ViewSchema,view 是 collectChildContainers 副作用,system.ts 处理
1174
- optionsBuilder: (c, _v) => {
1644
+ optionsBuilder: (c, _v) => ({
1645
+ type: c.type,
1646
+ elementsMargin: c.elementsMargin,
1647
+ padding: c.padding,
1648
+ vertPadding: c.vertPadding, horPadding: c.horPadding,
1649
+ topPadding: c.topPadding, bottomPadding: c.bottomPadding,
1650
+ leftPadding: c.leftPadding, rightPadding: c.rightPadding,
1651
+ maxWidth: c.maxWidth, maxHeight: c.maxHeight,
1652
+ }),
1653
+ postCreate: (inst, c) => {
1175
1654
  var _a;
1176
- return ({
1177
- type: c.type,
1178
- elementsMargin: c.elementsMargin,
1179
- padding: c.padding,
1180
- vertPadding: c.vertPadding, horPadding: c.horPadding,
1181
- topPadding: c.topPadding, bottomPadding: c.bottomPadding,
1182
- leftPadding: c.leftPadding, rightPadding: c.rightPadding,
1183
- maxWidth: c.maxWidth, maxHeight: c.maxHeight,
1184
- children: (_a = c.__resolved_items) !== null && _a !== void 0 ? _a : [],
1185
- });
1655
+ for (const item of (_a = c.__resolved_items) !== null && _a !== void 0 ? _a : []) {
1656
+ try {
1657
+ inst.addChild(item);
1658
+ }
1659
+ catch (_) { }
1660
+ }
1661
+ if (typeof inst.arrangeChildren === 'function')
1662
+ inst.arrangeChildren();
1186
1663
  },
1187
1664
  syncOnChange: (inst, c) => {
1188
1665
  if (inst.type !== c.type)
@@ -1192,6 +1669,7 @@ const LIST_DEF = {
1192
1669
  if (typeof inst.arrangeChildren === 'function')
1193
1670
  inst.arrangeChildren();
1194
1671
  },
1672
+ applySize: applyListLayoutSize,
1195
1673
  };
1196
1674
  const SCROLL_BOX_DEF = {
1197
1675
  name: 'ScrollBox',
@@ -1202,12 +1680,22 @@ const SCROLL_BOX_DEF = {
1202
1680
  height: { kind: 'scalar', default: 240, inspector: { name: 'height', type: 'number' } },
1203
1681
  direction: { kind: 'scalar', default: 'vertical', inspector: { name: 'direction', type: 'string' } },
1204
1682
  contentChildName: { kind: 'scalar', default: 'content' },
1205
- background: { kind: 'scalar', default: 0x111111, inspector: { name: 'background', type: 'color' } },
1683
+ background: { kind: 'scalar', inspector: { name: 'background', type: 'color' } },
1206
1684
  radius: { kind: 'scalar', default: 0, inspector: { name: 'radius', type: 'number' } },
1207
1685
  elementsMargin: { kind: 'scalar', default: 0 },
1208
1686
  disableDynamicRendering: { kind: 'scalar', default: false },
1209
1687
  disableEasing: { kind: 'scalar', default: false, inspector: { name: 'disableEasing', type: 'boolean' } },
1210
1688
  padding: { kind: 'scalar', default: 0 },
1689
+ vertPadding: { kind: 'scalar' },
1690
+ horPadding: { kind: 'scalar' },
1691
+ topPadding: { kind: 'scalar' },
1692
+ bottomPadding: { kind: 'scalar' },
1693
+ leftPadding: { kind: 'scalar' },
1694
+ rightPadding: { kind: 'scalar' },
1695
+ globalScroll: { kind: 'scalar', default: true },
1696
+ shiftScroll: { kind: 'scalar', default: false },
1697
+ proximityRange: { kind: 'scalar' },
1698
+ proximityDebounce: { kind: 'scalar' },
1211
1699
  // legacy fields(spec 兼容)
1212
1700
  inertia: { kind: 'scalar', default: true },
1213
1701
  inertiaDecay: { kind: 'scalar', default: 0.92 },
@@ -1219,7 +1707,7 @@ const SCROLL_BOX_DEF = {
1219
1707
  getBounds() { return { minX: 0, maxX: 0, minY: 0, maxY: 0 }; },
1220
1708
  },
1221
1709
  optionsBuilder: (c, _v) => {
1222
- var _a, _b;
1710
+ var _a;
1223
1711
  const typeMap = {
1224
1712
  horizontal: 'horizontal', vertical: 'vertical', both: 'bidirectional',
1225
1713
  };
@@ -1228,21 +1716,37 @@ const SCROLL_BOX_DEF = {
1228
1716
  type: (_a = typeMap[c.direction]) !== null && _a !== void 0 ? _a : 'vertical',
1229
1717
  background: c.background, radius: c.radius,
1230
1718
  elementsMargin: c.elementsMargin, padding: c.padding,
1719
+ vertPadding: c.vertPadding, horPadding: c.horPadding,
1720
+ topPadding: c.topPadding, bottomPadding: c.bottomPadding,
1721
+ leftPadding: c.leftPadding, rightPadding: c.rightPadding,
1231
1722
  disableEasing: c.disableEasing, disableDynamicRendering: c.disableDynamicRendering,
1232
- items: (_b = c.__resolved_items) !== null && _b !== void 0 ? _b : [],
1723
+ globalScroll: c.globalScroll, shiftScroll: c.shiftScroll,
1724
+ proximityRange: c.proximityRange, proximityDebounce: c.proximityDebounce,
1233
1725
  };
1234
1726
  },
1235
1727
  signalMap: () => ({
1236
1728
  scroll: (v) => ({ value: v }),
1237
1729
  }),
1238
- syncOnChange: (inst, c) => {
1730
+ postCreate: (inst, c) => {
1731
+ var _a, _b;
1732
+ if (typeof inst.addItems === 'function') {
1733
+ try {
1734
+ inst.addItems((_a = c.__resolved_items) !== null && _a !== void 0 ? _a : []);
1735
+ }
1736
+ catch (_) { }
1737
+ }
1738
+ if (typeof ((_b = inst.list) === null || _b === void 0 ? void 0 : _b.arrangeChildren) === 'function')
1739
+ inst.list.arrangeChildren();
1239
1740
  if (typeof inst.resize === 'function') {
1240
1741
  try {
1241
- inst.resize(c.width, c.height);
1742
+ inst.resize();
1242
1743
  }
1243
1744
  catch (_) { }
1244
1745
  }
1245
1746
  },
1747
+ syncOnChange: (inst, c) => {
1748
+ applyOptionalSize(inst, c);
1749
+ },
1246
1750
  };
1247
1751
  const SELECT_DEF = {
1248
1752
  name: 'Select',
@@ -1256,26 +1760,51 @@ const SELECT_DEF = {
1256
1760
  openView: { kind: 'opaque' },
1257
1761
  textStyle: { kind: 'shallowMerge', default: { fontFamily: 'Arial', fontSize: 14, fill: '#222' } },
1258
1762
  nineSliceSprite: { kind: 'opaque' },
1763
+ width: { kind: 'scalar', inspector: { name: 'width', type: 'number' } },
1764
+ height: { kind: 'scalar', inspector: { name: 'height', type: 'number' } },
1765
+ radius: { kind: 'scalar', default: 4 },
1766
+ visibleItems: { kind: 'scalar' },
1767
+ itemWidth: { kind: 'scalar' },
1768
+ itemHeight: { kind: 'scalar' },
1769
+ itemBackgroundColor: { kind: 'scalar', default: 0x000000 },
1770
+ itemHoverColor: { kind: 'scalar', default: 0x666666 },
1771
+ selectedTextOffset: { kind: 'shallowMerge', default: {} },
1772
+ scrollBox: { kind: 'shallowMerge', default: {} },
1773
+ textClass: { kind: 'scalar', default: 'text' },
1774
+ open: { kind: 'scalar', default: false },
1259
1775
  bindToStore: BIND_STORE,
1260
1776
  },
1261
1777
  views: {
1262
1778
  kind: 'object', folder: '__select_views__', keys: [],
1263
1779
  },
1264
1780
  optionsBuilder: (c) => {
1265
- var _a;
1781
+ var _a, _b, _d, _e, _f;
1266
1782
  return ({
1267
1783
  closedBG: c.__resolved_closedView,
1268
1784
  openBG: c.__resolved_openView,
1269
1785
  textStyle: c.textStyle,
1786
+ TextClass: c.textClass === 'html' ? pixi_js.HTMLText : undefined,
1787
+ selectedTextOffset: c.selectedTextOffset,
1270
1788
  items: {
1271
1789
  items: ((_a = c.items) !== null && _a !== void 0 ? _a : []).map((it) => it.text),
1272
- backgroundColor: 0x000000, hoverColor: 0x666666,
1273
- width: 200, height: 30, textStyle: c.textStyle, radius: 4,
1790
+ backgroundColor: c.itemBackgroundColor,
1791
+ hoverColor: c.itemHoverColor,
1792
+ width: (_d = (_b = c.itemWidth) !== null && _b !== void 0 ? _b : c.width) !== null && _d !== void 0 ? _d : 200,
1793
+ height: (_f = (_e = c.itemHeight) !== null && _e !== void 0 ? _e : c.height) !== null && _f !== void 0 ? _f : 30,
1794
+ textStyle: c.textStyle,
1795
+ TextClass: c.textClass === 'html' ? pixi_js.HTMLText : undefined,
1796
+ radius: c.radius,
1274
1797
  },
1275
1798
  selected: c.selectedIndex >= 0 ? c.selectedIndex : undefined,
1799
+ visibleItems: c.visibleItems,
1800
+ scrollBox: Object.assign({ width: c.width, height: c.height && c.visibleItems ? c.height * c.visibleItems : undefined, radius: c.radius }, c.scrollBox),
1276
1801
  nineSliceSprite: c.nineSliceSprite,
1277
1802
  });
1278
1803
  },
1804
+ postCreate: (inst, c) => {
1805
+ if (c.open && typeof inst.open === 'function')
1806
+ inst.open();
1807
+ },
1279
1808
  signalMap: (c) => ({
1280
1809
  select: (value, text) => {
1281
1810
  c.selectedIndex = value;
@@ -1283,6 +1812,12 @@ const SELECT_DEF = {
1283
1812
  return { index: value, text };
1284
1813
  },
1285
1814
  }),
1815
+ syncOnChange: (inst, c) => {
1816
+ if (c.open && typeof inst.open === 'function')
1817
+ inst.open();
1818
+ if (!c.open && typeof inst.close === 'function')
1819
+ inst.close();
1820
+ },
1286
1821
  };
1287
1822
  const DIALOG_DEF = {
1288
1823
  name: 'Dialog',
@@ -1301,36 +1836,340 @@ const DIALOG_DEF = {
1301
1836
  closeOnBackdropClick: { kind: 'scalar', default: true, inspector: { name: 'closeOnBackdropClick', type: 'boolean' } },
1302
1837
  contentChildName: { kind: 'scalar', default: 'content', inspector: { name: 'contentChildName', type: 'string' } },
1303
1838
  nineSliceSprite: { kind: 'opaque' },
1839
+ titleStyle: { kind: 'shallowMerge', default: {} },
1840
+ content: { kind: 'scalar' },
1841
+ contentStyle: { kind: 'shallowMerge', default: {} },
1842
+ contentButtons: { kind: 'arrayCopy', default: [] },
1843
+ contentCheckBoxes: { kind: 'arrayCopy', default: [] },
1844
+ buttons: { kind: 'arrayCopy', default: [] },
1845
+ buttonList: { kind: 'shallowMerge', default: {} },
1846
+ buttonListOffset: { kind: 'shallowMerge', default: {} },
1847
+ scrollBox: { kind: 'shallowMerge', default: {} },
1848
+ animations: { kind: 'opaque' },
1304
1849
  bindToStore: BIND_STORE,
1305
1850
  },
1306
1851
  optionsBuilder: (c) => {
1307
1852
  var _a;
1308
- return ({
1853
+ const background = c.nineSliceSprite && c.backgroundView && 'texture' in c.backgroundView
1854
+ ? c.backgroundView.texture
1855
+ : ((_a = c.__resolved_background_view) !== null && _a !== void 0 ? _a : new pixi_js.Container());
1856
+ return {
1309
1857
  backdrop: c.__resolved_backdropView,
1310
1858
  backdropColor: backdropColorToNumber(c.backdropColor),
1311
1859
  backdropAlpha: c.backdropAlpha,
1312
- background: (_a = c.__resolved_backgroundView) !== null && _a !== void 0 ? _a : new pixi_js.Container(),
1313
- title: c.title,
1860
+ background,
1861
+ title: makeDialogText(c.title, c.titleStyle),
1862
+ content: makeDialogContent(c),
1863
+ buttons: makeDialogButtons(c.buttons),
1864
+ buttonList: c.buttonList,
1865
+ scrollBox: c.scrollBox,
1314
1866
  width: c.width, height: c.height, padding: c.padding,
1315
1867
  closeOnBackdropClick: c.closeOnBackdropClick,
1316
1868
  nineSliceSprite: c.nineSliceSprite,
1317
- });
1869
+ animations: c.animations,
1870
+ };
1318
1871
  },
1319
1872
  postCreate: (inst, c) => {
1873
+ alignDialogAnchoredContent(inst, c);
1320
1874
  if (c.open && typeof inst.open === 'function')
1321
1875
  inst.open();
1322
1876
  },
1877
+ applySize: applyDialogSize,
1878
+ onAttachedExtra: (inst, c, go) => {
1879
+ wireDialogContentButtonPresses(inst, c, go);
1880
+ },
1323
1881
  signalMap: (c) => ({
1324
1882
  close: () => { c.open = false; return {}; },
1325
1883
  select: (idx, text) => ({ index: idx, text }),
1326
1884
  }),
1327
1885
  syncOnChange: (inst, c) => {
1886
+ alignDialogAnchoredContent(inst, c);
1328
1887
  if (c.open && !inst.isOpen && typeof inst.open === 'function')
1329
1888
  inst.open();
1330
1889
  else if (!c.open && inst.isOpen && typeof inst.close === 'function')
1331
1890
  inst.close();
1332
1891
  },
1333
1892
  };
1893
+ function applyDialogSize(inst, size, c) {
1894
+ var _a, _b, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _w, _x, _y;
1895
+ const width = readPositiveSize((_b = (_a = size.width) !== null && _a !== void 0 ? _a : c.width) !== null && _b !== void 0 ? _b : (_d = inst === null || inst === void 0 ? void 0 : inst.options) === null || _d === void 0 ? void 0 : _d.width);
1896
+ const height = readPositiveSize((_f = (_e = size.height) !== null && _e !== void 0 ? _e : c.height) !== null && _f !== void 0 ? _f : (_g = inst === null || inst === void 0 ? void 0 : inst.options) === null || _g === void 0 ? void 0 : _g.height);
1897
+ if (width === undefined && height === undefined)
1898
+ return;
1899
+ inst.options = (_h = inst.options) !== null && _h !== void 0 ? _h : {};
1900
+ if (width !== undefined)
1901
+ inst.options.width = width;
1902
+ if (height !== undefined)
1903
+ inst.options.height = height;
1904
+ const dialogWidth = width !== null && width !== void 0 ? width : (Number(inst.options.width) || Number((_j = inst.innerView) === null || _j === void 0 ? void 0 : _j.width) || 0);
1905
+ const dialogHeight = height !== null && height !== void 0 ? height : (Number(inst.options.height) || Number((_k = inst.innerView) === null || _k === void 0 ? void 0 : _k.height) || 0);
1906
+ const padding = Number((_m = (_l = c.padding) !== null && _l !== void 0 ? _l : inst.options.padding) !== null && _m !== void 0 ? _m : 20) || 20;
1907
+ if (inst.innerView) {
1908
+ if (width !== undefined)
1909
+ inst.innerView.width = width;
1910
+ if (height !== undefined)
1911
+ inst.innerView.height = height;
1912
+ if ('anchor' in inst.innerView && ((_o = inst.innerView.anchor) === null || _o === void 0 ? void 0 : _o.set)) {
1913
+ inst.innerView.anchor.set(0.5, 0.5);
1914
+ }
1915
+ else {
1916
+ try {
1917
+ (_q = (_p = inst.innerView.pivot) === null || _p === void 0 ? void 0 : _p.set) === null || _q === void 0 ? void 0 : _q.call(_p, dialogWidth / 2, dialogHeight / 2);
1918
+ }
1919
+ catch (_) { }
1920
+ }
1921
+ }
1922
+ if (inst.titleText) {
1923
+ inst.titleText.x = dialogWidth / 2;
1924
+ inst.titleText.y = padding;
1925
+ }
1926
+ const titleHeight = Number((_r = inst.titleText) === null || _r === void 0 ? void 0 : _r.height) || 0;
1927
+ const buttonHeight = Number((_s = inst.buttonContainer) === null || _s === void 0 ? void 0 : _s.height) || 0;
1928
+ if (inst.buttonContainer) {
1929
+ inst.buttonContainer.x = dialogWidth / 2 - ((Number(inst.buttonContainer.width) || 0) / 2);
1930
+ inst.buttonContainer.y = dialogHeight - padding - buttonHeight;
1931
+ }
1932
+ if (inst.scrollBox) {
1933
+ inst.scrollBox.x = padding;
1934
+ inst.scrollBox.y = padding + titleHeight;
1935
+ const overrideSize = (_t = c.scrollBox) === null || _t === void 0 ? void 0 : _t.size;
1936
+ const scrollWidth = (_u = readPositiveSize(overrideSize === null || overrideSize === void 0 ? void 0 : overrideSize.width)) !== null && _u !== void 0 ? _u : Math.max(0, dialogWidth - (padding * 2));
1937
+ const scrollHeight = (_w = readPositiveSize(overrideSize === null || overrideSize === void 0 ? void 0 : overrideSize.height)) !== null && _w !== void 0 ? _w : Math.max(0, dialogHeight - (padding * 2) - titleHeight - buttonHeight);
1938
+ if (typeof inst.scrollBox.setSize === 'function')
1939
+ inst.scrollBox.setSize(scrollWidth, scrollHeight);
1940
+ else {
1941
+ inst.scrollBox.width = scrollWidth;
1942
+ inst.scrollBox.height = scrollHeight;
1943
+ }
1944
+ try {
1945
+ (_y = (_x = inst.scrollBox).resize) === null || _y === void 0 ? void 0 : _y.call(_x, true);
1946
+ }
1947
+ catch (_) { }
1948
+ }
1949
+ alignDialogAnchoredContent(inst, Object.assign(Object.assign({}, c), { width: dialogWidth, height: dialogHeight }));
1950
+ }
1951
+ function readPositiveSize(value) {
1952
+ const n = Number(value);
1953
+ return Number.isFinite(n) && n > 0 ? n : undefined;
1954
+ }
1955
+ function alignDialogAnchoredContent(inst, c) {
1956
+ var _a, _b;
1957
+ const innerView = inst === null || inst === void 0 ? void 0 : inst.innerView;
1958
+ const contentView = inst === null || inst === void 0 ? void 0 : inst.contentView;
1959
+ if ((innerView === null || innerView === void 0 ? void 0 : innerView.anchor) && contentView && c.width && c.height) {
1960
+ contentView.x = -c.width / 2;
1961
+ contentView.y = -c.height / 2;
1962
+ }
1963
+ applyDialogOffset(inst, 'buttonListOffset', inst.buttonContainer, c.buttonListOffset);
1964
+ applyDialogOffset(inst, 'scrollBoxOffset', inst.scrollBox, (_a = c.scrollBox) === null || _a === void 0 ? void 0 : _a.offset);
1965
+ applyDialogScrollBoxSize(inst, (_b = c.scrollBox) === null || _b === void 0 ? void 0 : _b.size);
1966
+ }
1967
+ function applyDialogOffset(inst, key, target, nextOffset) {
1968
+ var _a, _b, _d, _e;
1969
+ if (!target)
1970
+ return;
1971
+ const applied = (_a = inst.__evaDialogAppliedOffsets) !== null && _a !== void 0 ? _a : {};
1972
+ const prev = (_b = applied[key]) !== null && _b !== void 0 ? _b : { x: 0, y: 0 };
1973
+ const next = { x: (_d = nextOffset === null || nextOffset === void 0 ? void 0 : nextOffset.x) !== null && _d !== void 0 ? _d : 0, y: (_e = nextOffset === null || nextOffset === void 0 ? void 0 : nextOffset.y) !== null && _e !== void 0 ? _e : 0 };
1974
+ target.x += next.x - prev.x;
1975
+ target.y += next.y - prev.y;
1976
+ inst.__evaDialogAppliedOffsets = Object.assign(Object.assign({}, applied), { [key]: next });
1977
+ }
1978
+ function applyDialogScrollBoxSize(inst, nextSize) {
1979
+ var _a, _b, _d;
1980
+ const scrollBox = inst === null || inst === void 0 ? void 0 : inst.scrollBox;
1981
+ if (!scrollBox)
1982
+ return;
1983
+ const base = (_a = inst.__evaDialogBaseScrollBoxSize) !== null && _a !== void 0 ? _a : {
1984
+ width: scrollBox.width,
1985
+ height: scrollBox.height,
1986
+ };
1987
+ inst.__evaDialogBaseScrollBoxSize = base;
1988
+ const wasApplied = inst.__evaDialogAppliedScrollBoxSize;
1989
+ if (!nextSize && !wasApplied)
1990
+ return;
1991
+ const width = (_b = nextSize === null || nextSize === void 0 ? void 0 : nextSize.width) !== null && _b !== void 0 ? _b : base.width;
1992
+ const height = (_d = nextSize === null || nextSize === void 0 ? void 0 : nextSize.height) !== null && _d !== void 0 ? _d : base.height;
1993
+ if (typeof scrollBox.setSize === 'function')
1994
+ scrollBox.setSize(width, height);
1995
+ else {
1996
+ scrollBox.width = width;
1997
+ scrollBox.height = height;
1998
+ }
1999
+ if (typeof scrollBox.resize === 'function')
2000
+ scrollBox.resize(true);
2001
+ inst.__evaDialogAppliedScrollBoxSize = !!nextSize;
2002
+ }
2003
+ function makeDialogText(text, style) {
2004
+ if (text === undefined)
2005
+ return undefined;
2006
+ if (style && Object.keys(style).length > 0) {
2007
+ return new pixi_js.Text({ text, style: style });
2008
+ }
2009
+ return text;
2010
+ }
2011
+ function makeDialogContent(c) {
2012
+ var _a, _b;
2013
+ if ((_a = c.contentButtons) === null || _a === void 0 ? void 0 : _a.length) {
2014
+ const records = [];
2015
+ const buttons = c.contentButtons.map((button, index) => {
2016
+ const pixiButton = new ui.FancyButton(makeDialogButtonOptions(button));
2017
+ applyOptionalSize(pixiButton, button);
2018
+ if (button.disabled !== undefined)
2019
+ pixiButton.enabled = !button.disabled;
2020
+ records.push({ button: pixiButton, params: button, index });
2021
+ return pixiButton;
2022
+ });
2023
+ c.__dialogContentButtons = records;
2024
+ return buttons;
2025
+ }
2026
+ if ((_b = c.contentCheckBoxes) === null || _b === void 0 ? void 0 : _b.length) {
2027
+ return c.contentCheckBoxes.map((checkBox) => new ui.CheckBox(makeDialogCheckBoxOptions(checkBox)));
2028
+ }
2029
+ return makeDialogText(c.content, c.contentStyle);
2030
+ }
2031
+ function wireDialogContentButtonPresses(inst, c, go) {
2032
+ const records = c.__dialogContentButtons;
2033
+ if (!Array.isArray(records) || records.length === 0 || inst.__evaDialogContentButtonPressesWired)
2034
+ return;
2035
+ inst.__evaDialogContentButtonPressesWired = true;
2036
+ inst.__evaDialogContentButtonPressCleanups = records.map((record) => {
2037
+ var _a;
2038
+ const signal = (_a = record.button) === null || _a === void 0 ? void 0 : _a.onPress;
2039
+ if (!signal || typeof signal.connect !== 'function')
2040
+ return undefined;
2041
+ const conn = signal.connect(() => {
2042
+ var _a, _b, _d, _e;
2043
+ const value = (_b = (_a = record.params.value) !== null && _a !== void 0 ? _a : record.params.text) !== null && _b !== void 0 ? _b : record.index;
2044
+ c.selectedContentIndex = record.index;
2045
+ c.selectedContentValue = value;
2046
+ c.selectCount = ((_d = c.selectCount) !== null && _d !== void 0 ? _d : 0) + 1;
2047
+ c.lastSignal = 'select';
2048
+ emitDialogSelection(go, { index: record.index, text: String((_e = record.params.text) !== null && _e !== void 0 ? _e : ''), value });
2049
+ if (record.params.closeOnPress && typeof inst.close === 'function')
2050
+ inst.close();
2051
+ const reopenDelay = Number(record.params.reopenDelay);
2052
+ if (Number.isFinite(reopenDelay) && reopenDelay >= 0 && typeof inst.open === 'function') {
2053
+ setTimeout(() => {
2054
+ try {
2055
+ inst.open();
2056
+ }
2057
+ catch (_) { }
2058
+ }, reopenDelay);
2059
+ }
2060
+ });
2061
+ return () => { try {
2062
+ conn.disconnect();
2063
+ }
2064
+ catch (_) { } };
2065
+ }).filter(Boolean);
2066
+ }
2067
+ function emitDialogSelection(go, payload) {
2068
+ var _a, _b, _d;
2069
+ const eventPayload = Object.assign({ entityName: go === null || go === void 0 ? void 0 : go.name }, payload);
2070
+ try {
2071
+ (_a = go === null || go === void 0 ? void 0 : go.emit) === null || _a === void 0 ? void 0 : _a.call(go, 'select', eventPayload);
2072
+ }
2073
+ catch (_) { }
2074
+ try {
2075
+ (_b = go === null || go === void 0 ? void 0 : go.emit) === null || _b === void 0 ? void 0 : _b.call(go, 'dialog:select', eventPayload);
2076
+ }
2077
+ catch (_) { }
2078
+ const mx = (typeof globalThis !== 'undefined' ? globalThis.mx : undefined);
2079
+ if ((_d = mx === null || mx === void 0 ? void 0 : mx.event) === null || _d === void 0 ? void 0 : _d.emit) {
2080
+ try {
2081
+ mx.event.emit('dialog:select', eventPayload);
2082
+ }
2083
+ catch (_) { }
2084
+ }
2085
+ }
2086
+ function makeDialogButtons(buttons) {
2087
+ if (!(buttons === null || buttons === void 0 ? void 0 : buttons.length))
2088
+ return undefined;
2089
+ return buttons.map((button) => {
2090
+ const options = makeDialogButtonOptions(button);
2091
+ const shouldMaterialize = button.disabled !== undefined
2092
+ || !!(button.nineSliceSprite && (button.width !== undefined || button.height !== undefined));
2093
+ if (button.kind === 'button' || !shouldMaterialize)
2094
+ return options;
2095
+ const pixiButton = new ui.FancyButton(options);
2096
+ applyOptionalSize(pixiButton, button);
2097
+ pixiButton.enabled = !button.disabled;
2098
+ return pixiButton;
2099
+ });
2100
+ }
2101
+ function makeDialogButtonOptions(button) {
2102
+ var _a, _b, _d, _e, _f, _g, _h, _j, _k, _l;
2103
+ if (button.kind === 'button')
2104
+ return makeDialogBareButton(button);
2105
+ const width = (_a = button.width) !== null && _a !== void 0 ? _a : 110;
2106
+ const height = (_b = button.height) !== null && _b !== void 0 ? _b : 48;
2107
+ const radius = (_d = button.radius) !== null && _d !== void 0 ? _d : 12;
2108
+ const color = (_e = button.color) !== null && _e !== void 0 ? _e : pixiStoryDefaultButtonColor;
2109
+ return {
2110
+ text: makeDialogText(button.text, button.textStyle),
2111
+ defaultView: (_f = resolveDialogButtonView(button.defaultView)) !== null && _f !== void 0 ? _f : makeDialogButtonView(width, height, radius, color),
2112
+ hoverView: (_g = resolveDialogButtonView(button.hoverView)) !== null && _g !== void 0 ? _g : makeDialogButtonView(width, height, radius, (_h = button.hoverColor) !== null && _h !== void 0 ? _h : color),
2113
+ pressedView: (_j = resolveDialogButtonView(button.pressedView)) !== null && _j !== void 0 ? _j : makeDialogButtonView(width, height, radius, (_k = button.pressedColor) !== null && _k !== void 0 ? _k : color),
2114
+ disabledView: (_l = resolveDialogButtonView(button.disabledView)) !== null && _l !== void 0 ? _l : (button.disabledColor ? makeDialogButtonView(width, height, radius, button.disabledColor) : undefined),
2115
+ nineSliceSprite: button.nineSliceSprite,
2116
+ enabled: button.disabled === undefined ? undefined : !button.disabled,
2117
+ animations: button.animations,
2118
+ };
2119
+ }
2120
+ function resolveDialogButtonView(view) {
2121
+ return view ? getTextureView(view) : undefined;
2122
+ }
2123
+ const pixiStoryDefaultButtonColor = '#e91e63';
2124
+ const pixiStoryDefaultTextColor = '#ffffff';
2125
+ function makeDialogButtonView(width, height, radius, color) {
2126
+ return new pixi_js.Graphics()
2127
+ .roundRect(0, 0, width, height, radius)
2128
+ .fill(color);
2129
+ }
2130
+ function makeDialogBareButton(button) {
2131
+ var _a, _b, _d, _e, _f, _g;
2132
+ const width = (_a = button.width) !== null && _a !== void 0 ? _a : 110;
2133
+ const height = (_b = button.height) !== null && _b !== void 0 ? _b : 48;
2134
+ const radius = (_d = button.radius) !== null && _d !== void 0 ? _d : 12;
2135
+ const view = makeDialogButtonView(width, height, radius, (_e = button.color) !== null && _e !== void 0 ? _e : pixiStoryDefaultButtonColor);
2136
+ const label = makeDialogText(button.text, button.textStyle);
2137
+ if (label) {
2138
+ label.x = width / 2;
2139
+ label.y = height / 2;
2140
+ try {
2141
+ (_g = (_f = label.anchor) === null || _f === void 0 ? void 0 : _f.set) === null || _g === void 0 ? void 0 : _g.call(_f, 0.5);
2142
+ }
2143
+ catch (_) { }
2144
+ view.addChild(label);
2145
+ }
2146
+ const pixiButton = new ui.Button(view);
2147
+ if (button.disabled !== undefined)
2148
+ pixiButton.enabled = !button.disabled;
2149
+ return pixiButton;
2150
+ }
2151
+ function makeDialogCheckBoxOptions(checkBox) {
2152
+ var _a, _b, _d, _e, _f, _g;
2153
+ const size = (_a = checkBox.size) !== null && _a !== void 0 ? _a : 30;
2154
+ const radius = (_b = checkBox.radius) !== null && _b !== void 0 ? _b : 5;
2155
+ const strokeColor = (_d = checkBox.strokeColor) !== null && _d !== void 0 ? _d : pixiStoryDefaultTextColor;
2156
+ const strokeWidth = (_e = checkBox.strokeWidth) !== null && _e !== void 0 ? _e : 2;
2157
+ return {
2158
+ style: {
2159
+ unchecked: new pixi_js.Graphics()
2160
+ .roundRect(0, 0, size, size, radius)
2161
+ .fill(((_f = checkBox.uncheckedColor) !== null && _f !== void 0 ? _f : '#3e3f40'))
2162
+ .stroke({ color: strokeColor, width: strokeWidth }),
2163
+ checked: new pixi_js.Graphics()
2164
+ .roundRect(0, 0, size, size, radius)
2165
+ .fill(((_g = checkBox.checkedColor) !== null && _g !== void 0 ? _g : pixiStoryDefaultButtonColor))
2166
+ .stroke({ color: strokeColor, width: strokeWidth }),
2167
+ text: checkBox.textStyle,
2168
+ },
2169
+ text: checkBox.text,
2170
+ checked: checkBox.checked,
2171
+ };
2172
+ }
1334
2173
  const MASKED_FRAME_DEF = {
1335
2174
  name: 'MaskedFrame',
1336
2175
  signalPrefix: 'maskedframe',
@@ -1339,12 +2178,14 @@ const MASKED_FRAME_DEF = {
1339
2178
  targetView: { kind: 'opaque' },
1340
2179
  maskView: { kind: 'opaque' },
1341
2180
  borderView: { kind: 'opaque' },
2181
+ borderWidth: { kind: 'scalar', default: 0, inspector: { name: 'borderWidth', type: 'number' } },
2182
+ borderColor: { kind: 'scalar', default: 0x000000, inspector: { name: 'borderColor', type: 'color' } },
1342
2183
  },
1343
2184
  optionsBuilder: (c) => ({
1344
- target: c.__resolved_targetView,
1345
- mask: c.__resolved_maskView,
1346
- borderWidth: 0,
1347
- borderColor: 0,
2185
+ target: c.__resolved_target_view,
2186
+ mask: c.__resolved_mask_view,
2187
+ borderWidth: c.borderWidth,
2188
+ borderColor: c.borderColor,
1348
2189
  }),
1349
2190
  };
1350
2191
  // ============================================================
@@ -1394,6 +2235,12 @@ class RadioGroup extends eva_js.Component {
1394
2235
  constructor() {
1395
2236
  super(...arguments);
1396
2237
  this.componentName = 'RadioGroup';
2238
+ // 显式 `= undefined`:被 UISystem 的 `@componentObserver({ RadioGroup: ['selectedId', ...] })`
2239
+ // 观察;applyParams 里 `if (typeof p.selectedId === 'string')` 是条件赋值,
2240
+ // 默认 RadioGroup 无选中时 own property 不存在,observer.ts:236 会打
2241
+ // "prop selectedId not in component: RadioGroup, Can not observer" 并跳过
2242
+ // 响应式挂载,后续 `radioGroup.selectedId = 'xxx'` 也不会经 UISystem 同步子 CheckBox。
2243
+ this.selectedId = undefined;
1397
2244
  this.direction = 'vertical';
1398
2245
  this.elementsMargin = 4;
1399
2246
  /** runtime: 已绑定的子 CheckBox(System 填充) */
@@ -1541,13 +2388,16 @@ function safeProject(projector, args) {
1541
2388
  /**
1542
2389
  * UISystem - generic handler driven by COMPONENT_DEFINITIONS metadata.
1543
2390
  *
1544
- * 16 个 ECS 组件(UI 自渲染 + 14 个 @pixi/ui factory wrapper + RadioGroup 独立)由本 system 统一驱动。
2391
+ * 16 个 ECS 组件(Shape 自渲染 + 14 个 @pixi/ui factory wrapper + RadioGroup 独立)由本 system 统一驱动。
1545
2392
  * 不再为每个组件写独立 handler 方法 - 14 个 @pixi/ui 组件走 handleGeneric,RadioGroup 单独处理。
1546
2393
  */
1547
2394
  // observer schema:把 COMPONENT_DEFINITIONS.fields 转成 componentObserver decorator 参数
1548
2395
  function buildObserverSchema() {
1549
2396
  const out = {
2397
+ Transform: [{ prop: ['size'], deep: true }],
2398
+ Shape: [{ prop: ['shapes'], deep: true }],
1550
2399
  UI: [{ prop: ['shapes'], deep: true }],
2400
+ UIComponent: [{ prop: ['shapes'], deep: true }],
1551
2401
  RadioGroup: [
1552
2402
  { prop: ['selectedId'], deep: false },
1553
2403
  { prop: ['direction'], deep: false },
@@ -1564,6 +2414,9 @@ function buildObserverSchema() {
1564
2414
  }
1565
2415
  return out;
1566
2416
  }
2417
+ function isShapeComponentName(name) {
2418
+ return name === 'Shape' || name === 'UI' || name === 'UIComponent';
2419
+ }
1567
2420
  let UISystem = class UISystem extends eva_js.System {
1568
2421
  constructor() {
1569
2422
  super(...arguments);
@@ -1571,6 +2424,7 @@ let UISystem = class UISystem extends eva_js.System {
1571
2424
  /** componentName -> instance map(generic 共享一份) */
1572
2425
  this.instances = new Map();
1573
2426
  this.signalCleanups = new Map();
2427
+ this.transformSizeAuthorities = new Set();
1574
2428
  this.radioGroupInstances = new Map();
1575
2429
  }
1576
2430
  /** 给 RadioGroup 反查 PixiCheckBox 实例用 */
@@ -1594,8 +2448,10 @@ let UISystem = class UISystem extends eva_js.System {
1594
2448
  }
1595
2449
  componentChanged(changed) {
1596
2450
  const name = changed.componentName;
1597
- if (name === 'UI')
1598
- return this.handleUI(changed);
2451
+ if (name === 'Transform')
2452
+ return this.handleTransformSizeChanged(changed);
2453
+ if (isShapeComponentName(name))
2454
+ return this.handleShape(changed);
1599
2455
  if (name === 'RadioGroup')
1600
2456
  return this.handleRadioGroup(changed);
1601
2457
  const def = COMPONENT_DEFINITIONS[name];
@@ -1603,13 +2459,13 @@ let UISystem = class UISystem extends eva_js.System {
1603
2459
  return this.handleGeneric(def, changed);
1604
2460
  }
1605
2461
  // ============================================================
1606
- // UI(自渲染,无 @pixi/ui 实例)
2462
+ // Shape(自渲染,无 @pixi/ui 实例)
1607
2463
  // ============================================================
1608
- handleUI(changed) {
2464
+ handleShape(changed) {
1609
2465
  if (changed.type === eva_js.OBSERVER_TYPE.ADD || changed.type === eva_js.OBSERVER_TYPE.CHANGE) {
1610
- const ui = changed.component;
1611
- if (typeof ui.redraw === 'function')
1612
- ui.redraw();
2466
+ const shape = changed.component;
2467
+ if (typeof shape.redraw === 'function')
2468
+ shape.redraw();
1613
2469
  }
1614
2470
  }
1615
2471
  // ============================================================
@@ -1633,13 +2489,16 @@ let UISystem = class UISystem extends eva_js.System {
1633
2489
  return;
1634
2490
  }
1635
2491
  (_a = def.syncOnChange) === null || _a === void 0 ? void 0 : _a.call(def, inst, c);
2492
+ if (this.transformSizeAuthorities.has(go.id)) {
2493
+ applyTransformSizeToInstance(def, inst, c, go, 'component-change');
2494
+ }
1636
2495
  }
1637
2496
  else if (changed.type === eva_js.OBSERVER_TYPE.REMOVE) {
1638
2497
  this.detachGeneric(go.id, instMap, go);
1639
2498
  }
1640
2499
  }
1641
2500
  attachGeneric(def, c, go, instMap) {
1642
- var _a, _b, _c, _d, _f, _g, _h;
2501
+ var _a, _b, _c, _d, _f, _g, _h, _j, _k;
1643
2502
  if (instMap.has(go.id))
1644
2503
  return;
1645
2504
  const game = this.gameRef(go);
@@ -1656,25 +2515,39 @@ let UISystem = class UISystem extends eva_js.System {
1656
2515
  if (def.name === 'List' || def.name === 'ScrollBox') {
1657
2516
  const childName = def.name === 'List' ? c.itemsChildName : c.contentChildName;
1658
2517
  c.__resolved_items = collectChildContainers(game, go, childName);
2518
+ const expectedCount = getCollectedChildCount(go, childName);
2519
+ if (expectedCount > 0 && c.__resolved_items.length < expectedCount && ((_a = c.__collect_retry) !== null && _a !== void 0 ? _a : 0) < 10) {
2520
+ c.__collect_retry = ((_b = c.__collect_retry) !== null && _b !== void 0 ? _b : 0) + 1;
2521
+ requestAnimationFrame(() => this.attachGeneric(def, c, go, instMap));
2522
+ return;
2523
+ }
1659
2524
  }
1660
2525
  // 4) 构造 PIXI 实例
2526
+ const restoreTransientSize = this.applyTransientTransformSize(c, go);
1661
2527
  const built = def.optionsBuilder(c, views !== null && views !== void 0 ? views : {});
1662
2528
  const inst = def.positional
1663
2529
  ? new def.pixiClass(...built)
1664
2530
  : new def.pixiClass(built);
1665
2531
  // 5) postCreate(enabled / selected tint 等)
1666
- (_a = def.postCreate) === null || _a === void 0 ? void 0 : _a.call(def, inst, c);
2532
+ (_c = def.postCreate) === null || _c === void 0 ? void 0 : _c.call(def, inst, c);
2533
+ // 5.5) 新 DSL 以 Transform.size 作为 plugin-ui 渲染尺寸来源。
2534
+ // 历史 DSL 若显式写了组件 width/height,初次 attach 保持旧行为;之后 Transform.size change 会接管。
2535
+ if (this.transformSizeAuthorities.has(go.id) || !hasExplicitRenderSize(c)) {
2536
+ const applied = applyTransformSizeToInstance(def, inst, c, go, 'initial-transform');
2537
+ if (applied)
2538
+ this.transformSizeAuthorities.add(go.id);
2539
+ }
1667
2540
  // 6) 注册 + attach
1668
2541
  instMap.set(go.id, inst);
1669
2542
  attachToGameObject(game, go, inst);
1670
2543
  // 7) onAttachedExtra(Dialog 挂 contentChild)
1671
2544
  if (def.name === 'Dialog') {
1672
- const contentChild = findChildEntity(go, (_b = c.contentChildName) !== null && _b !== void 0 ? _b : 'content');
2545
+ const contentChild = findChildEntity(go, (_d = c.contentChildName) !== null && _d !== void 0 ? _d : 'content');
1673
2546
  if (contentChild) {
1674
2547
  const cc = getEvaContainer(game, contentChild);
1675
2548
  if (cc) {
1676
2549
  try {
1677
- (_d = (_c = inst).addChild) === null || _d === void 0 ? void 0 : _d.call(_c, cc);
2550
+ (_g = (_f = inst).addChild) === null || _g === void 0 ? void 0 : _g.call(_f, cc);
1678
2551
  }
1679
2552
  catch (_) { }
1680
2553
  }
@@ -1685,7 +2558,7 @@ let UISystem = class UISystem extends eva_js.System {
1685
2558
  const border = resolveViewRef(game, go, c.borderView);
1686
2559
  if (border) {
1687
2560
  try {
1688
- (_g = (_f = inst).addChild) === null || _g === void 0 ? void 0 : _g.call(_f, border);
2561
+ (_j = (_h = inst).addChild) === null || _j === void 0 ? void 0 : _j.call(_h, border);
1689
2562
  }
1690
2563
  catch (_) { }
1691
2564
  }
@@ -1695,7 +2568,8 @@ let UISystem = class UISystem extends eva_js.System {
1695
2568
  const offs = bridgeSignals(inst, { go, prefix: def.signalPrefix }, def.signalMap(c));
1696
2569
  this.signalCleanups.set(go.id, offs);
1697
2570
  }
1698
- (_h = def.onAttachedExtra) === null || _h === void 0 ? void 0 : _h.call(def, inst, c, go, game);
2571
+ (_k = def.onAttachedExtra) === null || _k === void 0 ? void 0 : _k.call(def, inst, c, go, game);
2572
+ restoreTransientSize();
1699
2573
  }
1700
2574
  detachGeneric(id, instMap, go) {
1701
2575
  const inst = instMap.get(id);
@@ -1772,6 +2646,11 @@ let UISystem = class UISystem extends eva_js.System {
1772
2646
  items, type: (_f = typeMap[c.direction]) !== null && _f !== void 0 ? _f : 'vertical',
1773
2647
  elementsMargin: c.elementsMargin, selectedItem: initialIndex,
1774
2648
  });
2649
+ if (this.transformSizeAuthorities.has(go.id)) {
2650
+ const size = readTransformRenderSize(go, { allowZero: true });
2651
+ if (size)
2652
+ applyRuntimeSize(inst, size);
2653
+ }
1775
2654
  this.radioGroupInstances.set(go.id, inst);
1776
2655
  attachToGameObject(game, go, inst);
1777
2656
  const offs = bridgeSignals(inst, { go, prefix: 'radiogroup' }, {
@@ -1807,6 +2686,74 @@ let UISystem = class UISystem extends eva_js.System {
1807
2686
  }
1808
2687
  return null;
1809
2688
  }
2689
+ // ============================================================
2690
+ // Transform.size -> plugin-ui runtime size
2691
+ // ============================================================
2692
+ handleTransformSizeChanged(changed) {
2693
+ var _a, _b;
2694
+ if (changed.type !== eva_js.OBSERVER_TYPE.CHANGE)
2695
+ return;
2696
+ const transform = changed.component;
2697
+ const go = (_a = changed.gameObject) !== null && _a !== void 0 ? _a : transform === null || transform === void 0 ? void 0 : transform.gameObject;
2698
+ if (!go)
2699
+ return;
2700
+ let applied = false;
2701
+ for (const [componentName, def] of Object.entries(COMPONENT_DEFINITIONS)) {
2702
+ const inst = (_b = this.instances.get(componentName)) === null || _b === void 0 ? void 0 : _b.get(go.id);
2703
+ if (!inst)
2704
+ continue;
2705
+ const component = getComponentSafe(go, componentName);
2706
+ if (applyTransformSizeToInstance(def, inst, component, go, 'transform-change')) {
2707
+ applied = true;
2708
+ }
2709
+ }
2710
+ const radioGroup = this.radioGroupInstances.get(go.id);
2711
+ if (radioGroup) {
2712
+ const size = readTransformRenderSize(go, { allowZero: true });
2713
+ if (size) {
2714
+ applyRuntimeSize(radioGroup, size);
2715
+ applied = true;
2716
+ }
2717
+ }
2718
+ if (applied)
2719
+ this.transformSizeAuthorities.add(go.id);
2720
+ this.relayoutLayoutInstances();
2721
+ }
2722
+ relayoutLayoutInstances() {
2723
+ for (const name of ['List', 'ScrollBox']) {
2724
+ const instMap = this.instances.get(name);
2725
+ if (!instMap)
2726
+ continue;
2727
+ for (const inst of instMap.values()) {
2728
+ relayoutRuntimeInstance(inst);
2729
+ }
2730
+ }
2731
+ }
2732
+ applyTransientTransformSize(c, go) {
2733
+ if (hasExplicitRenderSize(c))
2734
+ return () => { };
2735
+ const size = readTransformRenderSize(go);
2736
+ if (!size)
2737
+ return () => { };
2738
+ const hadWidth = Object.prototype.hasOwnProperty.call(c, 'width');
2739
+ const hadHeight = Object.prototype.hasOwnProperty.call(c, 'height');
2740
+ const prevWidth = c.width;
2741
+ const prevHeight = c.height;
2742
+ if (size.width !== undefined)
2743
+ c.width = size.width;
2744
+ if (size.height !== undefined)
2745
+ c.height = size.height;
2746
+ return () => {
2747
+ if (hadWidth)
2748
+ c.width = prevWidth;
2749
+ else
2750
+ delete c.width;
2751
+ if (hadHeight)
2752
+ c.height = prevHeight;
2753
+ else
2754
+ delete c.height;
2755
+ };
2756
+ }
1810
2757
  };
1811
2758
  UISystem.systemName = 'UISystem';
1812
2759
  UISystem = __decorate([
@@ -1827,10 +2774,16 @@ var UISystem$1 = UISystem;
1827
2774
  */
1828
2775
  function inlineResolveSpecialViews(name, c, game, go) {
1829
2776
  switch (name) {
1830
- case 'ProgressBar':
2777
+ case 'ProgressBar': {
2778
+ const fillView = c.nineSliceSprite
2779
+ ? c.fillView
2780
+ : normalizeProgressFillViewRef(c.fillView, c.fillPaddings, { width: c.width, height: c.height });
1831
2781
  c.__resolved_bg = resolveViewRef(game, go, c.bgView);
1832
- c.__resolved_fill = resolveViewRef(game, go, c.fillView);
2782
+ c.__resolved_fill = resolveViewRef(game, go, fillView);
2783
+ c.__resolved_bg_view = c.nineSliceSprite && c.bgView && 'texture' in c.bgView ? c.bgView.texture : c.__resolved_bg;
2784
+ c.__resolved_fill_view = c.nineSliceSprite && c.fillView && 'texture' in c.fillView ? c.fillView.texture : c.__resolved_fill;
1833
2785
  break;
2786
+ }
1834
2787
  case 'Select':
1835
2788
  c.__resolved_closedView = resolveViewRef(game, go, c.closedView);
1836
2789
  c.__resolved_openView = resolveViewRef(game, go, c.openView);
@@ -1838,10 +2791,15 @@ function inlineResolveSpecialViews(name, c, game, go) {
1838
2791
  case 'Dialog':
1839
2792
  c.__resolved_backdropView = resolveViewRef(game, go, c.backdropView);
1840
2793
  c.__resolved_backgroundView = resolveViewRef(game, go, c.backgroundView);
2794
+ c.__resolved_background_view = c.nineSliceSprite && c.backgroundView && 'texture' in c.backgroundView
2795
+ ? c.backgroundView.texture
2796
+ : c.__resolved_backgroundView;
1841
2797
  break;
1842
2798
  case 'MaskedFrame':
1843
2799
  c.__resolved_targetView = resolveViewRef(game, go, c.targetView);
1844
2800
  c.__resolved_maskView = resolveViewRef(game, go, c.maskView);
2801
+ c.__resolved_target_view = c.targetView && 'texture' in c.targetView ? c.targetView.texture : c.__resolved_targetView;
2802
+ c.__resolved_mask_view = c.maskView && 'texture' in c.maskView ? c.maskView.texture : c.__resolved_maskView;
1845
2803
  break;
1846
2804
  }
1847
2805
  }
@@ -1849,14 +2807,14 @@ function inlineResolveSpecialViews(name, c, game, go) {
1849
2807
  function validateInlineResolved(name, c) {
1850
2808
  switch (name) {
1851
2809
  case 'ProgressBar':
1852
- return !!(c.__resolved_bg && c.__resolved_fill);
2810
+ return !!(c.__resolved_bg_view && c.__resolved_fill_view);
1853
2811
  case 'Select':
1854
2812
  return !!(c.__resolved_closedView && c.__resolved_openView);
1855
2813
  case 'Dialog':
1856
2814
  // backgroundView 可 fallback PixiContainer,backdropView 也可 null
1857
2815
  return true;
1858
2816
  case 'MaskedFrame':
1859
- return !!(c.__resolved_targetView && c.__resolved_maskView);
2817
+ return !!(c.__resolved_target_view && c.__resolved_mask_view);
1860
2818
  default:
1861
2819
  return true;
1862
2820
  }
@@ -1874,15 +2832,47 @@ function collectChildContainers(game, go, childName) {
1874
2832
  continue;
1875
2833
  const childContainer = getEvaContainer(game, child);
1876
2834
  if (childContainer) {
2835
+ if (childContainer.width <= 0 || childContainer.height <= 0)
2836
+ continue;
1877
2837
  try {
1878
2838
  (_c = (_b = childContainer.parent) === null || _b === void 0 ? void 0 : _b.removeChild) === null || _c === void 0 ? void 0 : _c.call(_b, childContainer);
1879
2839
  }
1880
2840
  catch (_) { }
1881
- result.push(childContainer);
2841
+ result.push(wrapLayoutItem(childContainer, child));
1882
2842
  }
1883
2843
  }
1884
2844
  return result;
1885
2845
  }
2846
+ function wrapLayoutItem(childContainer, child) {
2847
+ const wrapper = new pixi_js.Container();
2848
+ const childName = child === null || child === void 0 ? void 0 : child.name;
2849
+ wrapper.label = childName ? `${childName}:layout-item` : 'plugin-ui-layout-item';
2850
+ wrapper.addChild(childContainer);
2851
+ Object.defineProperty(wrapper, 'width', {
2852
+ get: () => resolveLayoutItemSize(child, childContainer, 'width'),
2853
+ set: () => { },
2854
+ configurable: true,
2855
+ });
2856
+ Object.defineProperty(wrapper, 'height', {
2857
+ get: () => resolveLayoutItemSize(child, childContainer, 'height'),
2858
+ set: () => { },
2859
+ configurable: true,
2860
+ });
2861
+ return wrapper;
2862
+ }
2863
+ function resolveLayoutItemSize(child, childContainer, key) {
2864
+ var _a, _b;
2865
+ const transformSize = Number((_b = (_a = child === null || child === void 0 ? void 0 : child.transform) === null || _a === void 0 ? void 0 : _a.size) === null || _b === void 0 ? void 0 : _b[key]);
2866
+ if (Number.isFinite(transformSize) && transformSize > 0)
2867
+ return transformSize;
2868
+ const containerSize = Number(childContainer === null || childContainer === void 0 ? void 0 : childContainer[key]);
2869
+ return Number.isFinite(containerSize) ? containerSize : 0;
2870
+ }
2871
+ function getCollectedChildCount(go, childName) {
2872
+ var _a, _b, _c;
2873
+ const contentChild = findChildEntity(go, childName);
2874
+ return (_c = (_b = (_a = contentChild === null || contentChild === void 0 ? void 0 : contentChild.transform) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0;
2875
+ }
1886
2876
  function findChildEntity(go, name) {
1887
2877
  var _a, _b;
1888
2878
  if (!go)
@@ -1901,6 +2891,15 @@ function findChildEntity(go, name) {
1901
2891
  return tf.gameObject;
1902
2892
  }
1903
2893
  return null;
2894
+ }
2895
+ function getComponentSafe(go, componentName) {
2896
+ var _a;
2897
+ try {
2898
+ return (_a = go === null || go === void 0 ? void 0 : go.getComponent) === null || _a === void 0 ? void 0 : _a.call(go, componentName);
2899
+ }
2900
+ catch (_) {
2901
+ return undefined;
2902
+ }
1904
2903
  }
1905
2904
 
1906
2905
  exports.Button = Button;
@@ -1919,8 +2918,10 @@ exports.ProgressBar = ProgressBar;
1919
2918
  exports.RadioGroup = RadioGroup;
1920
2919
  exports.ScrollBox = ScrollBox;
1921
2920
  exports.Select = Select;
2921
+ exports.Shape = Shape;
1922
2922
  exports.Slider = Slider;
1923
2923
  exports.Switcher = Switcher;
1924
- exports.UI = UI;
2924
+ exports.UI = Shape;
2925
+ exports.UIShapeType = UIShapeType;
1925
2926
  exports.UISystem = UISystem$1;
1926
2927
  exports.defineUiComponent = defineUiComponent;