diff --git a/src/util/ui.js b/src/util/ui.js index c2d03cc..8d01ac1 100644 --- a/src/util/ui.js +++ b/src/util/ui.js @@ -1,20 +1,48 @@ +import Phaser from 'phaser'; import { WORLD_SCALE } from '../config.js'; +import { PILL_RADIUS } from './pill.js'; + +// Rounded-rect blue button - same look as the old flat Rectangle button, +// just with rounded corners matching the pills (PILL_RADIUS). Graphics +// instead of a Rectangle because only Graphics can round corners; the +// hover highlight re-draws the fill, keeping the dark outline. +const FILL = 0x2255aa; +const HOVER_FILL = 0x2f6ac0; +const STROKE = 0x1a1f29; +const STROKE_WIDTH = 2 * WORLD_SCALE; + +function drawBg(g, width, height, fill) { + g.clear(); + g.fillStyle(fill, 1); + g.fillRoundedRect(-width / 2, -height / 2, width, height, PILL_RADIUS); + g.lineStyle(STROKE_WIDTH, STROKE, 1); + g.strokeRoundedRect(-width / 2, -height / 2, width, height, PILL_RADIUS); +} export function createButton(scene, x, y, label, onClick, options = {}) { const width = options.width || 220 * WORLD_SCALE; const height = options.height || 56 * WORLD_SCALE; const fontSize = options.fontSize || `${20 * WORLD_SCALE}px`; - const bg = scene.add.rectangle(x, y, width, height, 0x2255aa).setStrokeStyle(2 * WORLD_SCALE, 0x1a1f29); + const bg = scene.add.graphics().setPosition(x, y); + drawBg(bg, width, height, FILL); const text = scene.add.text(x, y, label, { fontFamily: 'monospace', fontSize, color: '#ffffff', }).setOrigin(0.5); - bg.setInteractive({ useHandCursor: true }); - bg.on('pointerover', () => bg.setFillStyle(0x2f6ac0)); - bg.on('pointerout', () => bg.setFillStyle(0x2255aa)); + // Explicit hit rect - a default setInteractive() on a Graphics would use + // its full 512x512 texture frame, making clicks near other buttons land + // on the wrong one. Graphics hit areas live in its local drawing space + // (displayOrigin 0,0), so the rect mirrors the drawn rounded rect. + bg.setInteractive({ + hitArea: new Phaser.Geom.Rectangle(-width / 2, -height / 2, width, height), + hitAreaCallback: Phaser.Geom.Rectangle.Contains, + useHandCursor: true, + }); + bg.on('pointerover', () => drawBg(bg, width, height, HOVER_FILL)); + bg.on('pointerout', () => drawBg(bg, width, height, FILL)); bg.on('pointerdown', onClick); return { bg, text };