@combos-fun/plugin-development-tool 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/combos-plugin.json +2 -1
- package/dist/plugin-development-tool.cjs.js +180 -103
- package/dist/plugin-development-tool.cjs.js.map +1 -1
- package/dist/plugin-development-tool.cjs.prod.js +1 -1
- package/dist/plugin-development-tool.d.ts +38 -28
- package/dist/plugin-development-tool.esm.js +180 -104
- package/dist/plugin-development-tool.esm.js.map +1 -1
- package/package.json +5 -5
package/combos-plugin.json
CHANGED
|
@@ -8,7 +8,9 @@ var pluginRendererEvent = require('@combos-fun/plugin-renderer-event');
|
|
|
8
8
|
|
|
9
9
|
/** Toggle development-tool selection / parent postMessage. Payload: `{ enabled: boolean }`. */
|
|
10
10
|
const COMBOS_DEVELOPMENT_TOOL_SET = 'combos-development-tool:set';
|
|
11
|
-
/**
|
|
11
|
+
/** iframe → parent: `setEnabled` finished (pick attach after enable, or restore after disable). Payload: `{ enabled: boolean }`. */
|
|
12
|
+
const COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS = 'combos-development-tool:set-success';
|
|
13
|
+
/** Re-scan the scene tree while the development tool is enabled. */
|
|
12
14
|
const COMBOS_DEVELOPMENT_TOOL_REFRESH = 'combos-development-tool:refresh';
|
|
13
15
|
/** Emitted to `window.parent` when an object is selected while the tool is on. */
|
|
14
16
|
const COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = 'combos-development-tool:gameobject-selected';
|
|
@@ -18,8 +20,9 @@ const COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY = 'combos-development-tool:apply-pr
|
|
|
18
20
|
const COMBOS_DEVELOPMENT_TOOL_READY = 'combos-development-tool:ready';
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
+
* Marks a `GameObject` as selectable in editor pick mode. While the development tool is enabled,
|
|
24
|
+
* only nodes carrying this component receive a pick `Event`; all other game `Event` components
|
|
25
|
+
* are removed and cached until disable.
|
|
23
26
|
*/
|
|
24
27
|
class CombosDevelopmentToolTarget extends engine.Component {
|
|
25
28
|
constructor() {
|
|
@@ -272,31 +275,33 @@ function applyPropertyWithHooks(go, componentName, path, value) {
|
|
|
272
275
|
|
|
273
276
|
const OUTLINE_GO_NAME = '__combosDevelopmentToolOutline';
|
|
274
277
|
/**
|
|
275
|
-
* **
|
|
276
|
-
*
|
|
278
|
+
* **Off** at start. While enabled:
|
|
279
|
+
* - strips `Event` from every scene `GameObject` (cached for restore on disable);
|
|
280
|
+
* - attaches pick `Event` + outline only on nodes with {@link CombosDevelopmentToolTarget}.
|
|
281
|
+
*
|
|
277
282
|
* Turn on/off via:
|
|
278
283
|
* - `window.dispatchEvent(new CustomEvent(COMBOS_DEVELOPMENT_TOOL_SET, { detail: { enabled: true } }))`
|
|
279
284
|
* - `window.postMessage({ type: COMBOS_DEVELOPMENT_TOOL_SET, enabled: true }, targetOrigin)` (e.g. from parent iframe)
|
|
280
285
|
* - `game.emit(COMBOS_DEVELOPMENT_TOOL_SET, { enabled: true })` or `getSystem(CombosDevelopmentToolSystem).setEnabled(true)`
|
|
281
286
|
*
|
|
282
|
-
*
|
|
287
|
+
* While enabled: `game.emit(COMBOS_DEVELOPMENT_TOOL_REFRESH)`, `window` event `combos-development-tool:refresh`,
|
|
288
|
+
* or `postMessage({ type: 'combos-development-tool:refresh' })` to re-bind after adding/removing objects.
|
|
283
289
|
*/
|
|
284
290
|
let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends engine.System {
|
|
285
291
|
constructor() {
|
|
286
292
|
super(...arguments);
|
|
287
293
|
this.postMessageOrigin = '*';
|
|
288
|
-
this.scope = 'scene';
|
|
289
294
|
this.enabled = false;
|
|
290
295
|
this.outlineGo = null;
|
|
291
296
|
this.selected = null;
|
|
292
297
|
this.tapHandlers = new Map();
|
|
293
298
|
this.tapOwners = new Map();
|
|
294
|
-
/** Game `
|
|
295
|
-
this.
|
|
296
|
-
/**
|
|
297
|
-
this.
|
|
298
|
-
this.
|
|
299
|
-
this.
|
|
299
|
+
/** Game `Event` components removed while enabled; restored on disable. */
|
|
300
|
+
this.cachedGameEvents = new Map();
|
|
301
|
+
/** Pick `Event` injected for {@link CombosDevelopmentToolTarget} nodes. */
|
|
302
|
+
this.pickEvents = new Set();
|
|
303
|
+
this.needsRescan = false;
|
|
304
|
+
this.lastOutlineBounds = null;
|
|
300
305
|
this.onWindowSet = (e) => {
|
|
301
306
|
const d = e.detail;
|
|
302
307
|
if (d && typeof d.enabled === 'boolean') {
|
|
@@ -332,7 +337,6 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
332
337
|
static { this.systemName = 'CombosDevelopmentToolSystem'; }
|
|
333
338
|
init(params) {
|
|
334
339
|
this.postMessageOrigin = params?.postMessageOrigin ?? '*';
|
|
335
|
-
this.scope = params?.scope ?? 'scene';
|
|
336
340
|
if (typeof window !== 'undefined') {
|
|
337
341
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_SET, this.onWindowSet);
|
|
338
342
|
window.addEventListener(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onWindowRefresh);
|
|
@@ -340,11 +344,8 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
340
344
|
}
|
|
341
345
|
this.game.on(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
342
346
|
this.game.on(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
343
|
-
if (this.enabled
|
|
344
|
-
this.
|
|
345
|
-
}
|
|
346
|
-
else if (this.enabled && this.scope === 'tagged') {
|
|
347
|
-
this.needsTaggedRescan = true;
|
|
347
|
+
if (this.enabled) {
|
|
348
|
+
this.needsRescan = true;
|
|
348
349
|
}
|
|
349
350
|
}
|
|
350
351
|
onDestroy() {
|
|
@@ -355,7 +356,8 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
355
356
|
}
|
|
356
357
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_SET, this.onGameSet);
|
|
357
358
|
this.game.off(COMBOS_DEVELOPMENT_TOOL_REFRESH, this.onGameRefresh);
|
|
358
|
-
this.
|
|
359
|
+
this.detachAllPicks();
|
|
360
|
+
this.restoreCachedGameEvents();
|
|
359
361
|
this.clearSelection();
|
|
360
362
|
}
|
|
361
363
|
/** Programmatic toggle (same effect as events). */
|
|
@@ -365,99 +367,72 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
365
367
|
this.enabled = on;
|
|
366
368
|
if (!on) {
|
|
367
369
|
this.clearSelection();
|
|
368
|
-
this.
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
this.needsSceneRescan = true;
|
|
370
|
+
this.detachAllPicks();
|
|
371
|
+
this.restoreCachedGameEvents();
|
|
372
|
+
this.postSetSuccess(false);
|
|
372
373
|
}
|
|
373
374
|
else {
|
|
374
|
-
this.
|
|
375
|
+
this.needsRescan = true;
|
|
375
376
|
}
|
|
376
377
|
}
|
|
377
378
|
get isEnabled() {
|
|
378
379
|
return this.enabled;
|
|
379
380
|
}
|
|
380
381
|
update(e) {
|
|
381
|
-
if (this.enabled && this.
|
|
382
|
-
this.
|
|
383
|
-
this.
|
|
384
|
-
|
|
385
|
-
if (this.enabled && this.needsTaggedRescan && this.scope === 'tagged') {
|
|
386
|
-
this.needsTaggedRescan = false;
|
|
387
|
-
this.attachTaggedObjects();
|
|
382
|
+
if (this.enabled && this.needsRescan) {
|
|
383
|
+
this.needsRescan = false;
|
|
384
|
+
this.attachEditMode();
|
|
385
|
+
this.postSetSuccess(true);
|
|
388
386
|
}
|
|
389
387
|
for (const go of [...this.tapOwners.values()]) {
|
|
390
388
|
if (go.destroyed) {
|
|
391
|
-
this.
|
|
389
|
+
this.releasePick(go);
|
|
392
390
|
}
|
|
393
391
|
}
|
|
394
392
|
if (!this.enabled || !this.selected || !this.outlineGo)
|
|
395
393
|
return;
|
|
396
|
-
|
|
397
|
-
if (!gfxComp?.graphics)
|
|
398
|
-
return;
|
|
399
|
-
const bounds = this.resolvePickBounds(this.selected);
|
|
400
|
-
const g = gfxComp.graphics;
|
|
401
|
-
g.clear();
|
|
402
|
-
const t = typeof performance !== 'undefined' ? performance.now() : e.time;
|
|
403
|
-
const pulse = 0.35 + 0.65 * (0.5 + 0.5 * Math.sin(t * 0.012));
|
|
404
|
-
g.rect(bounds.x, bounds.y, bounds.width, bounds.height);
|
|
405
|
-
g.stroke({ width: 4, color: 0x55ffaa, alpha: pulse });
|
|
394
|
+
this.updateSelectionOutline();
|
|
406
395
|
}
|
|
407
396
|
componentChanged(changed) {
|
|
408
|
-
if (this.
|
|
397
|
+
if (!this.enabled)
|
|
409
398
|
return;
|
|
410
399
|
const { type, gameObject, componentName } = changed;
|
|
411
400
|
if (!gameObject || componentName !== 'CombosDevelopmentToolTarget')
|
|
412
401
|
return;
|
|
413
402
|
if (type === engine.OBSERVER_TYPE.ADD) {
|
|
414
|
-
this.
|
|
403
|
+
this.stripGameEvent(gameObject);
|
|
404
|
+
this.ensurePick(gameObject);
|
|
415
405
|
}
|
|
416
406
|
else if (type === engine.OBSERVER_TYPE.REMOVE) {
|
|
417
|
-
this.
|
|
407
|
+
this.releasePick(gameObject);
|
|
418
408
|
if (this.selected === gameObject) {
|
|
419
409
|
this.clearSelection();
|
|
420
410
|
}
|
|
421
411
|
}
|
|
422
412
|
}
|
|
423
|
-
/** Re-bind
|
|
413
|
+
/** Re-bind pick targets after dynamic scene changes while enabled. */
|
|
424
414
|
requestSceneRescan() {
|
|
425
415
|
if (!this.enabled)
|
|
426
416
|
return;
|
|
427
|
-
|
|
428
|
-
this.needsSceneRescan = true;
|
|
429
|
-
}
|
|
430
|
-
else {
|
|
431
|
-
this.needsTaggedRescan = true;
|
|
432
|
-
}
|
|
417
|
+
this.needsRescan = true;
|
|
433
418
|
}
|
|
434
|
-
|
|
419
|
+
attachEditMode() {
|
|
420
|
+
this.detachAllPicks();
|
|
435
421
|
const list = [];
|
|
436
422
|
for (const tr of this.game.scene.transform.children) {
|
|
437
423
|
this.collectGameObjects(tr.gameObject, list);
|
|
438
424
|
}
|
|
439
425
|
for (const go of list) {
|
|
440
|
-
if (go
|
|
441
|
-
continue;
|
|
442
|
-
if (go === this.outlineGo)
|
|
426
|
+
if (this.isIgnoredPickGo(go))
|
|
443
427
|
continue;
|
|
444
|
-
|
|
445
|
-
continue;
|
|
446
|
-
this.ensureTap(go);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
attachSceneTree() {
|
|
450
|
-
this.detachAllTaps(false);
|
|
451
|
-
const list = [];
|
|
452
|
-
for (const tr of this.game.scene.transform.children) {
|
|
453
|
-
this.collectGameObjects(tr.gameObject, list);
|
|
428
|
+
this.stripGameEvent(go);
|
|
454
429
|
}
|
|
455
430
|
for (const go of list) {
|
|
456
|
-
if (go
|
|
431
|
+
if (this.isIgnoredPickGo(go))
|
|
457
432
|
continue;
|
|
458
|
-
if (go
|
|
433
|
+
if (!go.getComponent(CombosDevelopmentToolTarget))
|
|
459
434
|
continue;
|
|
460
|
-
this.
|
|
435
|
+
this.ensurePick(go);
|
|
461
436
|
}
|
|
462
437
|
}
|
|
463
438
|
collectGameObjects(go, out) {
|
|
@@ -466,30 +441,58 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
466
441
|
this.collectGameObjects(tr.gameObject, out);
|
|
467
442
|
}
|
|
468
443
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
444
|
+
isIgnoredPickGo(go) {
|
|
445
|
+
return go.name === OUTLINE_GO_NAME || go === this.outlineGo;
|
|
446
|
+
}
|
|
447
|
+
stripGameEvent(go) {
|
|
448
|
+
if (this.cachedGameEvents.has(go.id))
|
|
449
|
+
return;
|
|
450
|
+
const ev = go.getComponent(pluginRendererEvent.Event);
|
|
451
|
+
if (!ev)
|
|
452
|
+
return;
|
|
453
|
+
try {
|
|
454
|
+
const removed = go.removeComponent(pluginRendererEvent.Event);
|
|
455
|
+
this.cachedGameEvents.set(go.id, removed);
|
|
456
|
+
}
|
|
457
|
+
catch {
|
|
458
|
+
/* ignore */
|
|
472
459
|
}
|
|
473
460
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
461
|
+
restoreCachedGameEvents() {
|
|
462
|
+
for (const [id, event] of [...this.cachedGameEvents.entries()]) {
|
|
463
|
+
const go = this.findGameObjectById(id);
|
|
464
|
+
if (!go || go.destroyed || go.getComponent(pluginRendererEvent.Event)) {
|
|
465
|
+
this.cachedGameEvents.delete(id);
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
try {
|
|
469
|
+
go.addComponent(event);
|
|
470
|
+
}
|
|
471
|
+
catch {
|
|
472
|
+
/* ignore */
|
|
473
|
+
}
|
|
474
|
+
this.cachedGameEvents.delete(id);
|
|
479
475
|
}
|
|
476
|
+
}
|
|
477
|
+
detachAllPicks() {
|
|
478
|
+
for (const go of [...this.tapOwners.values()]) {
|
|
479
|
+
this.releasePick(go);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
ensurePick(go) {
|
|
480
483
|
if (this.tapHandlers.has(go.id))
|
|
481
484
|
return;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
this.
|
|
485
|
+
let ev = go.getComponent(pluginRendererEvent.Event);
|
|
486
|
+
if (!ev) {
|
|
487
|
+
ev = go.addComponent(this.createPickEvent(go));
|
|
488
|
+
this.pickEvents.add(go.id);
|
|
485
489
|
}
|
|
486
|
-
ev.removeAllListeners('tap');
|
|
487
490
|
const handler = payload => this.onSelect(go, payload);
|
|
488
491
|
this.tapHandlers.set(go.id, handler);
|
|
489
492
|
this.tapOwners.set(go.id, go);
|
|
490
493
|
ev.on('tap', handler);
|
|
491
494
|
}
|
|
492
|
-
|
|
495
|
+
createPickEvent(go) {
|
|
493
496
|
const bounds = this.resolvePickBounds(go);
|
|
494
497
|
if (bounds.width > 0 && bounds.height > 0) {
|
|
495
498
|
return new pluginRendererEvent.Event({
|
|
@@ -504,13 +507,14 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
504
507
|
},
|
|
505
508
|
});
|
|
506
509
|
}
|
|
507
|
-
// Let Pixi use natural rendered bounds instead of forcing a 1×1 hit area.
|
|
508
510
|
return new pluginRendererEvent.Event();
|
|
509
511
|
}
|
|
510
512
|
resolvePickBounds(go) {
|
|
511
|
-
// Graphics draws in arbitrary local coordinates (often centered at 0,0).
|
|
512
|
-
// transform.size is a layout box from (0,0) and must not override Pixi bounds.
|
|
513
513
|
if (this.shouldPreferRenderedBounds(go)) {
|
|
514
|
+
const fromOwnGraphics = this.resolveOwnGraphicsLocalBounds(go);
|
|
515
|
+
if (fromOwnGraphics) {
|
|
516
|
+
return fromOwnGraphics;
|
|
517
|
+
}
|
|
514
518
|
const fromGraphics = this.resolveContainerLocalBounds(go);
|
|
515
519
|
if (fromGraphics) {
|
|
516
520
|
return fromGraphics;
|
|
@@ -529,10 +533,37 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
529
533
|
shouldPreferRenderedBounds(go) {
|
|
530
534
|
return go.getComponent(pluginRendererGraphics.Graphics) != null;
|
|
531
535
|
}
|
|
536
|
+
/** Bounds of this GO's own Graphics only — excludes child GOs such as the selection outline. */
|
|
537
|
+
resolveOwnGraphicsLocalBounds(go) {
|
|
538
|
+
const gfx = go.getComponent(pluginRendererGraphics.Graphics);
|
|
539
|
+
if (!gfx?.graphics)
|
|
540
|
+
return null;
|
|
541
|
+
try {
|
|
542
|
+
const bounds = gfx.graphics.getLocalBounds();
|
|
543
|
+
if (bounds.width > 0 && bounds.height > 0) {
|
|
544
|
+
return {
|
|
545
|
+
x: bounds.x,
|
|
546
|
+
y: bounds.y,
|
|
547
|
+
width: bounds.width,
|
|
548
|
+
height: bounds.height,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
catch {
|
|
553
|
+
/* ignore */
|
|
554
|
+
}
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
532
557
|
resolveContainerLocalBounds(go) {
|
|
533
558
|
const container = this.getRendererContainer(go);
|
|
534
559
|
if (!container)
|
|
535
560
|
return null;
|
|
561
|
+
const outlineContainer = this.getOutlineContainerIfChildOf(go);
|
|
562
|
+
let outlineDetached = false;
|
|
563
|
+
if (outlineContainer?.parent === container) {
|
|
564
|
+
container.removeChild(outlineContainer);
|
|
565
|
+
outlineDetached = true;
|
|
566
|
+
}
|
|
536
567
|
try {
|
|
537
568
|
const bounds = container.getLocalBounds();
|
|
538
569
|
if (bounds.width > 0 && bounds.height > 0) {
|
|
@@ -547,8 +578,20 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
547
578
|
catch {
|
|
548
579
|
/* ignore */
|
|
549
580
|
}
|
|
581
|
+
finally {
|
|
582
|
+
if (outlineDetached && outlineContainer) {
|
|
583
|
+
container.addChild(outlineContainer);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
550
586
|
return null;
|
|
551
587
|
}
|
|
588
|
+
/** Outline is parented under the selected GO; exclude it when measuring content bounds. */
|
|
589
|
+
getOutlineContainerIfChildOf(go) {
|
|
590
|
+
if (!this.outlineGo || this.outlineGo.parent !== go) {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
return this.getRendererContainer(this.outlineGo);
|
|
594
|
+
}
|
|
552
595
|
getRendererContainer(go) {
|
|
553
596
|
const rendererSystem = this.game.getSystem(pluginRenderer.RendererSystem);
|
|
554
597
|
if (!rendererSystem?.containerManager)
|
|
@@ -560,7 +603,7 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
560
603
|
return null;
|
|
561
604
|
}
|
|
562
605
|
}
|
|
563
|
-
|
|
606
|
+
releasePick(go) {
|
|
564
607
|
const handler = this.tapHandlers.get(go.id);
|
|
565
608
|
if (!handler)
|
|
566
609
|
return;
|
|
@@ -568,25 +611,26 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
568
611
|
ev?.off('tap', handler);
|
|
569
612
|
this.tapHandlers.delete(go.id);
|
|
570
613
|
this.tapOwners.delete(go.id);
|
|
571
|
-
if (
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
for (const fn of saved) {
|
|
575
|
-
ev.on('tap', fn);
|
|
576
|
-
}
|
|
614
|
+
if (this.pickEvents.has(go.id)) {
|
|
615
|
+
try {
|
|
616
|
+
go.removeComponent(pluginRendererEvent.Event);
|
|
577
617
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
try {
|
|
581
|
-
go.removeComponent(pluginRendererEvent.Event);
|
|
582
|
-
}
|
|
583
|
-
catch {
|
|
584
|
-
/* ignore */
|
|
585
|
-
}
|
|
586
|
-
this.injectedEvents.delete(go.id);
|
|
618
|
+
catch {
|
|
619
|
+
/* ignore */
|
|
587
620
|
}
|
|
621
|
+
this.pickEvents.delete(go.id);
|
|
588
622
|
}
|
|
589
623
|
}
|
|
624
|
+
postSetSuccess(enabled) {
|
|
625
|
+
const payload = {
|
|
626
|
+
type: COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS,
|
|
627
|
+
enabled,
|
|
628
|
+
};
|
|
629
|
+
if (typeof window !== 'undefined' && window.parent && window.parent !== window) {
|
|
630
|
+
window.parent.postMessage(payload, this.postMessageOrigin);
|
|
631
|
+
}
|
|
632
|
+
this.game.emit(COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS, { enabled });
|
|
633
|
+
}
|
|
590
634
|
ensureOutline() {
|
|
591
635
|
if (this.outlineGo)
|
|
592
636
|
return;
|
|
@@ -610,6 +654,8 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
610
654
|
this.outlineGo.remove();
|
|
611
655
|
}
|
|
612
656
|
go.addChild(this.outlineGo);
|
|
657
|
+
this.invalidateOutlineBounds();
|
|
658
|
+
this.updateSelectionOutline();
|
|
613
659
|
const snapshot = buildGameObjectSnapshot(go);
|
|
614
660
|
const payload = {
|
|
615
661
|
type: COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED,
|
|
@@ -681,6 +727,8 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
681
727
|
if (!applied)
|
|
682
728
|
return;
|
|
683
729
|
if (this.selected?.id === go.id) {
|
|
730
|
+
this.invalidateOutlineBounds();
|
|
731
|
+
this.updateSelectionOutline();
|
|
684
732
|
this.postSnapshotUpdate(go);
|
|
685
733
|
}
|
|
686
734
|
}
|
|
@@ -697,6 +745,7 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
697
745
|
}
|
|
698
746
|
clearSelection() {
|
|
699
747
|
this.selected = null;
|
|
748
|
+
this.invalidateOutlineBounds();
|
|
700
749
|
if (this.outlineGo?.parent) {
|
|
701
750
|
this.outlineGo.remove();
|
|
702
751
|
}
|
|
@@ -705,6 +754,33 @@ let CombosDevelopmentToolSystem$1 = class CombosDevelopmentToolSystem extends en
|
|
|
705
754
|
gfx.graphics.clear();
|
|
706
755
|
}
|
|
707
756
|
}
|
|
757
|
+
/** Redraw the green outline only when content bounds change (movement follows via child transform). */
|
|
758
|
+
updateSelectionOutline() {
|
|
759
|
+
if (!this.enabled || !this.selected || !this.outlineGo)
|
|
760
|
+
return;
|
|
761
|
+
const gfxComp = this.outlineGo.getComponent(pluginRendererGraphics.Graphics);
|
|
762
|
+
if (!gfxComp?.graphics)
|
|
763
|
+
return;
|
|
764
|
+
const bounds = this.resolvePickBounds(this.selected);
|
|
765
|
+
if (this.lastOutlineBounds && this.pickBoundsEqual(this.lastOutlineBounds, bounds)) {
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
this.lastOutlineBounds = bounds;
|
|
769
|
+
const g = gfxComp.graphics;
|
|
770
|
+
g.clear();
|
|
771
|
+
g.rect(bounds.x, bounds.y, bounds.width, bounds.height);
|
|
772
|
+
g.stroke({ width: 4, color: 0x55ffaa, alpha: 1 });
|
|
773
|
+
}
|
|
774
|
+
invalidateOutlineBounds() {
|
|
775
|
+
this.lastOutlineBounds = null;
|
|
776
|
+
}
|
|
777
|
+
pickBoundsEqual(a, b) {
|
|
778
|
+
const eps = 0.01;
|
|
779
|
+
return (Math.abs(a.x - b.x) < eps &&
|
|
780
|
+
Math.abs(a.y - b.y) < eps &&
|
|
781
|
+
Math.abs(a.width - b.width) < eps &&
|
|
782
|
+
Math.abs(a.height - b.height) < eps);
|
|
783
|
+
}
|
|
708
784
|
};
|
|
709
785
|
CombosDevelopmentToolSystem$1 = tslib.__decorate([
|
|
710
786
|
engine.decorators.componentObserver({
|
|
@@ -716,7 +792,7 @@ var CombosDevelopmentToolSystem = CombosDevelopmentToolSystem$1;
|
|
|
716
792
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
717
793
|
Object.assign(CombosDevelopmentToolSystem, {
|
|
718
794
|
packageName: "@combos-fun/plugin-development-tool",
|
|
719
|
-
packageVersion: "0.0.
|
|
795
|
+
packageVersion: "0.0.20",
|
|
720
796
|
});
|
|
721
797
|
|
|
722
798
|
exports.COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY = COMBOS_DEVELOPMENT_TOOL_APPLY_PROPERTY;
|
|
@@ -724,6 +800,7 @@ exports.COMBOS_DEVELOPMENT_TOOL_GAMEOBJECT_SELECTED = COMBOS_DEVELOPMENT_TOOL_GA
|
|
|
724
800
|
exports.COMBOS_DEVELOPMENT_TOOL_READY = COMBOS_DEVELOPMENT_TOOL_READY;
|
|
725
801
|
exports.COMBOS_DEVELOPMENT_TOOL_REFRESH = COMBOS_DEVELOPMENT_TOOL_REFRESH;
|
|
726
802
|
exports.COMBOS_DEVELOPMENT_TOOL_SET = COMBOS_DEVELOPMENT_TOOL_SET;
|
|
803
|
+
exports.COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS = COMBOS_DEVELOPMENT_TOOL_SET_SUCCESS;
|
|
727
804
|
exports.CombosDevelopmentToolSystem = CombosDevelopmentToolSystem;
|
|
728
805
|
exports.CombosDevelopmentToolTarget = CombosDevelopmentToolTarget;
|
|
729
806
|
exports.applyPropertyValue = applyPropertyValue;
|