Fix text centering and close-button click passthrough in UI windows

- Center the ✕ close glyph and "IN PROGRESS" labels via setOrigin(0.5, …);
  Phaser Text defaults to origin (0,0), so they were anchored top-left
  and sat off-center on their plates
- Widen detail buttons from 152 to 190 px so the widest label
  ("IN PROGRESS 88%") no longer bleeds past the plate edges
- Treat 'closing' as open in isOpen so a close tap is consumed by the
  window while it fades out, instead of leaking through as a world click
This commit is contained in:
Brian Fertig 2026-09-06 09:28:22 -06:00
parent 09dfd00dd3
commit ed890a35c3
2 changed files with 27 additions and 6 deletions

View File

@ -298,12 +298,15 @@ export class BuildWindow extends Phaser.GameObjects.Container {
const cy = rect.y + titleH / 2 - 2;
this.closeBtn = { x: cx, y: cy, w: cw, h: cw, hover: false };
this.closeG = G(2);
this.closeTxt = T(cx, cy - 5, '✕', {
this.closeTxt = T(cx, cy + 1, '✕', {
fontFamily: BODY,
fontSize: '15px',
color: toCss(C.neon2),
align: 'center',
}, 2);
// Text's default origin is (0,0) — without this the ✕ anchors its
// top-left at the plate centre and sits right-of-centre.
this.closeTxt.setOrigin(0.5, 0.5);
const closeRect = new Phaser.Geom.Rectangle(cx - cw / 2, cy - cw / 2, cw, cw);
this.closeG.setInteractive({
useHandCursor: true,
@ -915,7 +918,9 @@ export class BuildWindow extends Phaser.GameObjects.Container {
})
.setScrollFactor(0);
cont.add(this.dCost);
const btnW = 152;
// 190: the widest label is "IN PROGRESS 88%" (~166 px at 13px/ls-3) —
// 152 let it bleed past the plate edges.
const btnW = 190;
const wrapW = Math.max(120, rightX + rightW - 12 - btnW - 18 - tx);
this.dDesc = s
.text(tx, detailY + 80, '', {
@ -944,6 +949,7 @@ export class BuildWindow extends Phaser.GameObjects.Container {
letterSpacing: 3,
align: 'center',
})
.setOrigin(0.5, 0) // centre on the plate — text's default origin is (0,0)
.setScrollFactor(0);
const bar = s.graphics().setScrollFactor(0);
cont.add([g, label, bar]);
@ -1250,8 +1256,12 @@ export class BuildWindow extends Phaser.GameObjects.Container {
});
}
// 'closing' counts as open: the close button flips openState in the
// SAME input pass, before the scene's pointerdown guard runs — while
// the window is still on screen (fading out) it must keep owning the
// click, or the close tap leaks through as a world click.
get isOpen() {
return this.openState === 'open' || this.openState === 'opening';
return this.openState === 'open' || this.openState === 'opening' || this.openState === 'closing';
}
/** Repaint everything from state (after a build starts / completes). */

View File

@ -271,12 +271,15 @@ export class ResearchWindow extends Phaser.GameObjects.Container {
const cy = rect.y + titleH / 2 - 2;
this.closeBtn = { x: cx, y: cy, w: cw, h: cw, hover: false };
this.closeG = G(2);
this.closeTxt = T(cx, cy - 5, '✕', {
this.closeTxt = T(cx, cy + 1, '✕', {
fontFamily: BODY,
fontSize: '15px',
color: toCss(C.neon2),
align: 'center',
}, 2);
// Text's default origin is (0,0) — without this the ✕ anchors its
// top-left at the plate centre and sits right-of-centre.
this.closeTxt.setOrigin(0.5, 0.5);
// v4: setInteractive takes a config object — a bare shape (or the
// 4-arg Phaser-3 form) leaves input.hitAreaCallback unset and
// pointWithinHitArea throws on the first pointer move over it.
@ -835,7 +838,9 @@ export class ResearchWindow extends Phaser.GameObjects.Container {
})
.setScrollFactor(0);
cont.add(this.dUnlocks);
const btnW = 152;
// 190: the widest label is "IN PROGRESS 88%" (~166 px at 13px/ls-3) —
// 152 let it bleed past the plate edges.
const btnW = 190;
const wrapW = Math.max(120, rightX + rightW - 12 - btnW - 18 - tx);
this.dDesc = s
.text(tx, detailY + 76, '', {
@ -864,6 +869,7 @@ export class ResearchWindow extends Phaser.GameObjects.Container {
letterSpacing: 3,
align: 'center',
})
.setOrigin(0.5, 0) // centre on the plate — text's default origin is (0,0)
.setScrollFactor(0);
const bar = s.graphics().setScrollFactor(0);
// v4 Container.add(child, index) — multi-add is the ARRAY form.
@ -1264,8 +1270,13 @@ export class ResearchWindow extends Phaser.GameObjects.Container {
});
}
// 'closing' counts as open: the close button flips openState in the
// SAME input pass, before the scene's pointerdown guard runs — while
// the window is still on screen (fading out) it must keep owning the
// click, or the close tap leaks through as a world click (the ship
// flies at the ✕).
get isOpen() {
return this.openState === 'open' || this.openState === 'opening';
return this.openState === 'open' || this.openState === 'opening' || this.openState === 'closing';
}
/** Repaint everything from state (after research starts / completes). */