fluid/src/ui/button.ts
2024-05-04 15:29:30 +02:00

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
);
}
}