70 lines
1.8 KiB
TypeScript
70 lines
1.8 KiB
TypeScript
import { Canvas } from "@/canvas";
|
|
import { GameObject } from "@/common/gameobject";
|
|
import { Rect } from "@/common/rect";
|
|
import { Vec } from "@/common/vec";
|
|
import { fillRoundRect, fillTextCentered } from "@/graphics";
|
|
import { Colors } from "@/ui/colors";
|
|
|
|
export default class Button extends GameObject {
|
|
_rect: Rect;
|
|
label: string;
|
|
onclick: (btn: Button) => void;
|
|
parent: GameObject | undefined;
|
|
clicked: boolean;
|
|
hovered: boolean;
|
|
constructor(label: string, rect: Rect, onclick: (btn: Button) => void, parent?: GameObject) {
|
|
super();
|
|
this._rect = rect;
|
|
this.label = label;
|
|
this.onclick = onclick;
|
|
this.parent = parent;
|
|
this.clicked = false;
|
|
this.hovered = false;
|
|
}
|
|
|
|
get rect() {
|
|
if (!this.parent) {
|
|
return this._rect;
|
|
}
|
|
|
|
return this._rect.translate(this.parent.pos);
|
|
}
|
|
|
|
update({input}: Canvas) {
|
|
this.hovered = this.rect.contains(input.mousePos);
|
|
if (this.hovered && input.mousePressed) {
|
|
this.clicked = true;
|
|
}
|
|
if (!input.mouseDown) {
|
|
if (this.clicked && this.hovered) {
|
|
this.onclick(this);
|
|
}
|
|
this.clicked = false;
|
|
}
|
|
}
|
|
|
|
private get backgroundStyle() {
|
|
if (this.clicked) {
|
|
return Colors.BG_ACTIVE;
|
|
}
|
|
if (this.hovered) {
|
|
return Colors.BG_HOVER;
|
|
}
|
|
|
|
return Colors.BG;
|
|
}
|
|
|
|
|
|
render({ctx}: Canvas) {
|
|
ctx.fillStyle = this.backgroundStyle;
|
|
fillRoundRect(ctx, this.rect, 10);
|
|
ctx.fillStyle = Colors.TEXT;
|
|
fillTextCentered(
|
|
ctx,
|
|
this.label,
|
|
new Vec(this.rect.left, this.rect.top + this.rect.height / 2),
|
|
this.rect.width
|
|
);
|
|
}
|
|
}
|