Files
partey_workadventure/front/src/Phaser/Components/Ui/IconButton.ts
T
2022-04-25 17:16:21 +02:00

117 lines
3.3 KiB
TypeScript

export interface IconButtonConfig {
width: number;
height: number;
iconTextureKey: string;
idle: IconButtonAppearanceConfig;
hover: IconButtonAppearanceConfig;
pressed: IconButtonAppearanceConfig;
selected: IconButtonAppearanceConfig;
iconScale?: number;
}
export interface IconButtonAppearanceConfig {
color: number;
borderThickness: number;
borderColor: number;
}
export enum IconButtonEvent {
Clicked = "IconButton:Clicked",
}
export class IconButton extends Phaser.GameObjects.Container {
private background: Phaser.GameObjects.Graphics;
private icon: Phaser.GameObjects.Image;
private config: IconButtonConfig;
private hovered: boolean = false;
private pressed: boolean = false;
private selected: boolean = false;
constructor(scene: Phaser.Scene, x: number, y: number, config: IconButtonConfig) {
super(scene, x, y);
this.config = config;
this.background = this.scene.add.graphics();
this.icon = this.scene.add.image(0, 0, this.config.iconTextureKey).setScale(config.iconScale ?? 1);
this.drawBackground(this.config.idle);
this.add([this.background, this.icon]);
this.setSize(this.config.width, this.config.height);
this.setInteractive({ cursor: "pointer" });
this.bindEventHandlers();
this.scene.add.existing(this);
}
public select(select: boolean = true): void {
if (this.selected === select) {
return;
}
this.selected = select;
this.updateButtonAppearance();
}
private updateButtonAppearance(): void {
if (this.selected) {
this.drawBackground(this.config.selected);
return;
}
if (this.pressed) {
this.drawBackground(this.config.pressed);
return;
}
if (this.hovered) {
this.drawBackground(this.config.hover);
return;
}
this.drawBackground(this.config.idle);
}
private drawBackground(appearance: IconButtonAppearanceConfig): void {
this.background.clear();
this.background.fillStyle(appearance.color);
this.background.lineStyle(appearance.borderThickness, appearance.borderColor);
const w = this.config.width;
const h = this.config.height;
this.background.fillRect(-w / 2, -h / 2, w, h);
this.background.strokeRect(-w / 2, -h / 2, w, h);
}
private bindEventHandlers(): void {
this.on(Phaser.Input.Events.POINTER_OVER, () => {
if (this.selected) {
return;
}
this.hovered = true;
this.updateButtonAppearance();
});
this.on(Phaser.Input.Events.POINTER_OUT, () => {
this.hovered = false;
this.pressed = false;
this.updateButtonAppearance();
});
this.on(Phaser.Input.Events.POINTER_DOWN, () => {
if (this.selected) {
return;
}
this.pressed = true;
this.updateButtonAppearance();
});
this.on(Phaser.Input.Events.POINTER_UP, () => {
if (this.selected) {
return;
}
this.pressed = false;
this.updateButtonAppearance();
this.emit(IconButtonEvent.Clicked, this.selected);
});
}
}