Fix SET DESTINATION button overflow in shared ConfirmOverlay
- Add per-show width/height overrides so the SYSTEM tab's longer "SET DESTINATION" label gets a wider dialog than AUTOPILOT's ENGAGE - Grow each button panel to fit its label (_fitBtn) and re-flow title, body and buttons into the bottom band (_layout) instead of using fixed positions that let long text run past the panel edge - Record baseWidth so a grown button never stays wide for the next dialog - Wire map.json systemConfirm/confirm size config through MapWindow - Add ss-takeoff-02.mp4 asset
This commit is contained in:
parent
efe17f3d2e
commit
6609df2736
Binary file not shown.
|
|
@ -281,8 +281,10 @@
|
|||
"label": "ENGAGE"
|
||||
},
|
||||
"systemConfirm": {
|
||||
"_comment": "The SYSTEM tab's SET DESTINATION dialog (same shared ConfirmOverlay — the clicked object on a CHARTED star's chart; the ship isn't in that system, so no distance row / autopilot). The destination model is still being defined — CONFIRM acknowledges the pick through onSetDestination (systemId + objectId), CANCEL / scrim / ESC leave the map as it was.",
|
||||
"_comment": "The SYSTEM tab's SET DESTINATION dialog (same shared ConfirmOverlay — the clicked object on a CHARTED star's chart; the ship isn't in that system, so no distance row / autopilot). The destination model is still being defined — CONFIRM acknowledges the pick through onSetDestination (systemId + objectId), CANCEL / scrim / ESC leave the map as it was. width/height: wider than the AUTOPILOT dialog — the SET DESTINATION button is a long label, so the window gives the button room and the button grows to fit its text (ConfirmOverlay.show sizes it per label).",
|
||||
"title": "SET DESTINATION",
|
||||
"label": "SET DESTINATION"
|
||||
"label": "SET DESTINATION",
|
||||
"width": 520,
|
||||
"height": 176
|
||||
}
|
||||
}
|
||||
|
|
@ -120,6 +120,11 @@ export class ConfirmOverlay extends Phaser.GameObjects.Container {
|
|||
);
|
||||
this.confirmBtn.setAlpha(0);
|
||||
this.cancelBtn.setAlpha(0);
|
||||
// the natural widths (show() grows a button only as wide as its label
|
||||
// needs — and never leaves it grown for the NEXT dialog, which may
|
||||
// have a shorter label)
|
||||
this.confirmBtn.style.baseWidth = this.confirmBtn.style.width;
|
||||
this.cancelBtn.style.baseWidth = this.cancelBtn.style.width;
|
||||
this.add([this.cancelBtn, this.confirmBtn]);
|
||||
// Hidden dialog = inert buttons (same v4 `input.enabled` rule as the
|
||||
// scrim — otherwise the invisible CONFIRM/CANCEL swallow centre-
|
||||
|
|
@ -130,7 +135,49 @@ export class ConfirmOverlay extends Phaser.GameObjects.Container {
|
|||
this._titleDec = null;
|
||||
this._btnsUp = false;
|
||||
this._confirmUp = false;
|
||||
this._layout(); // size/label land in show(); positions derive from w/h
|
||||
}
|
||||
|
||||
/**
|
||||
* Place the title, body lines and the two buttons for the CURRENT
|
||||
* w/h + button sizes: the buttons sit in the panel's bottom band
|
||||
* (CANCEL left, CONFIRM right — each kept inside the panel edge with
|
||||
* a 20px margin, whatever its label grows it to).
|
||||
*/
|
||||
_layout() {
|
||||
this.title.setPosition(0, -this.h / 2 + 24);
|
||||
this.bodyTexts.forEach((t, i) => t.setPosition(0, -this.h / 2 + 52 + i * 17));
|
||||
const margin = 20;
|
||||
const cw = this.cancelBtn.style.width;
|
||||
const bw = this.confirmBtn.style.width;
|
||||
const bh = this.confirmBtn.style.height;
|
||||
const cy = this.h / 2 - margin - bh / 2;
|
||||
this.cancelBtn.setPosition(-this.w / 2 + margin + cw / 2, cy);
|
||||
this.confirmBtn.setPosition(this.w / 2 - margin - bw / 2, cy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Grow a button's panel to FIT its label (the SET DESTINATION label is
|
||||
* wider than the fixed 148px the CONFIRM button was built for — the
|
||||
* text used to run past the panel edge). Re-measures with the button's
|
||||
* own text style, then repaints + resets the hit area.
|
||||
*/
|
||||
_fitBtn(btn, label, minWidth) {
|
||||
const s = btn.style;
|
||||
const m = this.scene.add.text(0, 0, String(label), s.textStyle);
|
||||
const w = Math.max(s.baseWidth ?? s.width, minWidth, Math.ceil(m.width) + 28);
|
||||
m.destroy();
|
||||
if (w === s.width) return;
|
||||
s.width = w;
|
||||
btn.setSize(w, s.height);
|
||||
btn.panel.setInteractive({
|
||||
useHandCursor: true,
|
||||
hitArea: new Phaser.Geom.Rectangle(-w / 2, -s.height / 2, w, s.height),
|
||||
hitAreaCallback: (p, px, py) => Phaser.Geom.Rectangle.Contains(p, px, py),
|
||||
});
|
||||
btn.paint('base');
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Showing
|
||||
// ------------------------------------------------------------------
|
||||
|
|
@ -139,6 +186,9 @@ export class ConfirmOverlay extends Phaser.GameObjects.Container {
|
|||
* spec: {
|
||||
* title, body: string[], accent?: number,
|
||||
* confirmLabel?, cancelLabel?,
|
||||
* width?, height? — override the dialog's size for THIS show (the
|
||||
* SYSTEM tab's SET DESTINATION is wider than AUTOPILOT's ENGAGE —
|
||||
* its confirm label is longer); the layout re-flows for it,
|
||||
* onConfirm?, onCancel? — fired after the close animation lands
|
||||
* time — the engine time (for the open animation)
|
||||
* }
|
||||
|
|
@ -148,6 +198,11 @@ export class ConfirmOverlay extends Phaser.GameObjects.Container {
|
|||
this.onConfirm = typeof spec.onConfirm === 'function' ? spec.onConfirm : null;
|
||||
this.onCancel = typeof spec.onCancel === 'function' ? spec.onCancel : null;
|
||||
|
||||
// Per-show size (the SET DESTINATION dialog is wider than ENGAGE).
|
||||
if (Number(spec.width) > 0) this.w = Number(spec.width);
|
||||
if (Number(spec.height) > 0) this.h = Number(spec.height);
|
||||
this.setSize(this.w, this.h);
|
||||
|
||||
const setBtn = (btn, label) => {
|
||||
const s = String(label ?? '').toUpperCase();
|
||||
btn.labelText.setText(s);
|
||||
|
|
@ -156,6 +211,12 @@ export class ConfirmOverlay extends Phaser.GameObjects.Container {
|
|||
};
|
||||
setBtn(this.confirmBtn, spec.confirmLabel ?? 'CONFIRM');
|
||||
setBtn(this.cancelBtn, spec.cancelLabel ?? 'CANCEL');
|
||||
// The confirm button must FIT its label (the longest one is
|
||||
// SET DESTINATION) — grow the panel, then place both in the bottom
|
||||
// band, inside the panel edges.
|
||||
this._fitBtn(this.confirmBtn, String(spec.confirmLabel ?? 'CONFIRM').toUpperCase(), 110);
|
||||
this._fitBtn(this.cancelBtn, String(spec.cancelLabel ?? 'CANCEL').toUpperCase(), 88);
|
||||
this._layout();
|
||||
// Accent the confirm button's edge + hover glow.
|
||||
this.confirmBtn.style.stroke = this.accent;
|
||||
this.confirmBtn.style.neon = this.accent;
|
||||
|
|
|
|||
|
|
@ -2530,6 +2530,11 @@ export class MapWindow extends Phaser.GameObjects.Container {
|
|||
body: [`DESTINATION — ${label}`, sysName ? `SYSTEM — ${sysName}` : ''].filter(Boolean),
|
||||
accent: C.neon,
|
||||
confirmLabel: config.get('map.systemConfirm.label', 'SET DESTINATION'),
|
||||
// wider than AUTOPILOT's dialog — the SET DESTINATION label is
|
||||
// long, and it gets the room (button fits the text, text fits
|
||||
// the panel)
|
||||
width: config.get('map.systemConfirm.width', 520),
|
||||
height: config.get('map.systemConfirm.height', 176),
|
||||
onConfirm: () => {
|
||||
// the pick ripples once while the window fades out
|
||||
this._flash = { x: o.x + this.geo.mapX, y: o.y + this.geo.mapY, r: o.r, t0: this.scene.time.now };
|
||||
|
|
@ -2548,6 +2553,10 @@ export class MapWindow extends Phaser.GameObjects.Container {
|
|||
body,
|
||||
accent: C.amber,
|
||||
confirmLabel: config.get('map.confirm.label', 'ENGAGE'),
|
||||
// its own (narrower) size — the dialog instance is shared with the
|
||||
// wider SET DESTINATION one, so each call states its own footprint
|
||||
width: config.get('map.confirm.width', 440),
|
||||
height: config.get('map.confirm.height', 168),
|
||||
onConfirm: () => {
|
||||
// the pick ripples once while the window fades out
|
||||
this._flash = { x: o.x + this.geo.mapX, y: o.y + this.geo.mapY, r: o.r, t0: this.scene.time.now };
|
||||
|
|
|
|||
Loading…
Reference in New Issue