pokerogue/src/ui/modal-ui-handler.ts

139 lines
4.2 KiB
TypeScript
Raw Normal View History

import BattleScene from "../battle-scene";
2023-12-30 18:41:25 -05:00
import { TextStyle, addTextObject } from "./text";
import { Mode } from "./ui";
import UiHandler from "./ui-handler";
import { WindowVariant, addWindow } from "./ui-theme";
import {Button} from "#enums/buttons";
2023-12-30 18:41:25 -05:00
export interface ModalConfig {
buttonActions: Function[];
}
export abstract class ModalUiHandler extends UiHandler {
protected modalContainer: Phaser.GameObjects.Container;
protected modalBg: Phaser.GameObjects.NineSlice;
protected titleText: Phaser.GameObjects.Text;
protected buttonContainers: Phaser.GameObjects.Container[];
protected buttonBgs: Phaser.GameObjects.NineSlice[];
constructor(scene: BattleScene, mode?: Mode) {
[Refactor] use typescript `strict-null` (#3259) * TS: enable strict-null * fix battle-scene.ts * fix voucher.ts * adapt more files to strict-null * adapt more files to strict-null ( 2) * adapt ability.ts to strict-null * adapt `arena.ts` to strict-null * adapt TagAddedEvent constructor to strict-null * adapt phases.ts.to strict-null * adapt status-effect.ts to strict-null * adapt `account.ts` to strict-null * adapt `configHandler.ts` to strict-null * adapt `ability.ts` to strict-null * adapt `biomes.ts` to strict-null * adapt `challenge.ts` to strict-null * adapt `daily-run.ts` to strict-null * adapt `nature.ts` to strict-null * adapt `pokemon-forms.ts` to strict-null * adapt `tainer-names.ts` to strict-null * adapt `types.ts` to strict-null * adapt `weather.ts` to strict-null * adapt `egg-hatch-phase.ts` to strict-null * adapt `evolution-phase.ts` to strict-null * adapt `pokemon-sprite-sparkle-handler.ts` to strict-null * adapt `evolution-phase.ts` to strict-null * adapt `game-mode.ts` to strict-null * adapt `utils.ts` to strict-null * adapt `voucher-ui-handler.ts` to strict-null * adapt `src/ui/unavailable-modal-ui-handler.ts` to strict-null * adapt `src/ui/ui.ts` to strict-null * adapt `src/ui/ui-theme.ts` to strict-null * adapt `src/ui/title-ui-handler.ts` to strict-null * adapt `src/ui/time-of-day-widget.ts` to strict-null * adapt `src/ui/text.ts` to strict-null * adapt `src/ui/target-select-ui-handler.ts` to strict-null * adapt `src/ui/settings/settings-keyboard-ui-handler.ts` to strict-null * adapt more files to strict-null (3) * adapt more files to strict-null (4) * adapt more files (mostly tests) to strict-null (5) * adapt more files to strict-null (6) * adapt more files to strict-null (7) * Update `src/data/pokemon-evolutions.ts` for strict-null Partial update `src/data/pokemon-species.ts` for strict-null * adapt more files to strict-null (8) * adapt more files to strict-null (9) * Strict some more nulls (still a few errors remaining) * adapt rest of the files to strict-null (9) * fix tests (check for null instead of undefined) * repalce a lot of `??` with bangs And added TODO notice as usual * fix more tests * all tests pass now * fix broken game-loop after trainer battle add some console.warn for missing cases and falling back to default * remove guessed fallback from utils.rgbHexToRgba * add TODO for this.currentBattle = null * adjust getPokemonById() return to include `null` * fix compilation errors * add test for pokemon.trySetStatus * `chanceMultiplier` shouldn't be optional * allow `null` for currentPhase * adjust hasExpSprite logic for no keymatch found * reduce bang usage in account.updateUserInfo() * fix new strict-null issues after merge * fix `strict-null` issues in dropdown.ts and sand_spit.test.ts * fix egg-gacha * adapt gul_missile.test.ts to strict-null * fix move.ts strict-null * fix i18n.ts strict-null * fix strict-null issues * fix baton_pass test after accidentially breaking it * chore: fix compiler errors * revert accidential changes in baton_pass.test.ts --------- Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com>
2024-08-07 09:23:12 -07:00
super(scene, mode!); // TODO: is this bang correct?
2023-12-30 18:41:25 -05:00
this.buttonContainers = [];
this.buttonBgs = [];
}
abstract getModalTitle(config?: ModalConfig): string;
abstract getWidth(config?: ModalConfig): number;
abstract getHeight(config?: ModalConfig): number;
abstract getMargin(config?: ModalConfig): [number, number, number, number];
abstract getButtonLabels(config?: ModalConfig): string[];
2024-04-18 19:08:53 -04:00
getButtonTopMargin(): number {
return 0;
}
2023-12-30 18:41:25 -05:00
setup() {
const ui = this.getUi();
2024-05-24 01:45:04 +02:00
2023-12-30 18:41:25 -05:00
this.modalContainer = this.scene.add.container(0, 0);
this.modalContainer.setInteractive(new Phaser.Geom.Rectangle(0, 0, this.scene.game.canvas.width / 6, this.scene.game.canvas.height / 6), Phaser.Geom.Rectangle.Contains);
this.modalBg = addWindow(this.scene, 0, 0, 0, 0);
this.modalContainer.add(this.modalBg);
this.titleText = addTextObject(this.scene, 0, 4, "", TextStyle.SETTINGS_LABEL);
2023-12-30 18:41:25 -05:00
this.titleText.setOrigin(0.5, 0);
this.modalContainer.add(this.titleText);
ui.add(this.modalContainer);
const buttonLabels = this.getButtonLabels();
2024-04-18 19:08:53 -04:00
const buttonTopMargin = this.getButtonTopMargin();
for (const label of buttonLabels) {
2023-12-30 18:41:25 -05:00
const buttonLabel = addTextObject(this.scene, 0, 8, label, TextStyle.TOOLTIP_CONTENT);
buttonLabel.setOrigin(0.5, 0.5);
const buttonBg = addWindow(this.scene, 0, 0, buttonLabel.getBounds().width + 8, 16, false, false, 0, 0, WindowVariant.THIN);
buttonBg.setOrigin(0.5, 0);
buttonBg.setInteractive(new Phaser.Geom.Rectangle(0, 0, buttonBg.width, buttonBg.height), Phaser.Geom.Rectangle.Contains);
2024-04-18 19:08:53 -04:00
const buttonContainer = this.scene.add.container(0, buttonTopMargin);
2023-12-30 18:41:25 -05:00
this.buttonBgs.push(buttonBg);
this.buttonContainers.push(buttonContainer);
buttonContainer.add(buttonBg);
buttonContainer.add(buttonLabel);
this.modalContainer.add(buttonContainer);
}
this.modalContainer.setVisible(false);
}
show(args: any[]): boolean {
if (args.length >= 1 && "buttonActions" in args[0]) {
2023-12-30 18:41:25 -05:00
super.show(args);
const config = args[0] as ModalConfig;
this.updateContainer(config);
this.modalContainer.setVisible(true);
this.getUi().moveTo(this.modalContainer, this.getUi().length - 1);
for (let a = 0; a < this.buttonBgs.length; a++) {
if (a < this.buttonBgs.length) {
this.buttonBgs[a].on("pointerdown", (_) => config.buttonActions[a]());
}
2023-12-30 18:41:25 -05:00
}
return true;
}
return false;
}
updateContainer(config?: ModalConfig): void {
const [ marginTop, marginRight, marginBottom, marginLeft ] = this.getMargin(config);
2024-05-24 01:45:04 +02:00
2023-12-30 18:41:25 -05:00
const [ width, height ] = [ this.getWidth(config), this.getHeight(config) ];
this.modalContainer.setPosition((((this.scene.game.canvas.width / 6) - (width + (marginRight - marginLeft))) / 2), (((-this.scene.game.canvas.height / 6) - (height + (marginBottom - marginTop))) / 2));
this.modalBg.setSize(width, height);
const title = this.getModalTitle(config);
this.titleText.setText(title);
this.titleText.setX(width / 2);
this.titleText.setVisible(!!title);
for (let b = 0; b < this.buttonContainers.length; b++) {
const sliceWidth = width / (this.buttonContainers.length + 1);
this.buttonContainers[b].setPosition(sliceWidth * (b + 1), this.modalBg.height - (this.buttonBgs[b].height + 8));
}
}
processInput(button: Button): boolean {
return false;
}
clear() {
super.clear();
this.modalContainer.setVisible(false);
this.buttonBgs.map(bg => bg.off("pointerdown"));
2023-12-30 18:41:25 -05:00
}
}