mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-01-15 13:31:40 +00:00
[UI/UX][QoL] Ask confirmation before disabling touchpad controls in settings (#4949)
* [UI] Ask Confirmation before disabling touch controls * show a message when asking for confirmation in settings * small cleanup * change settings message box to display 2 lines with word wrap
This commit is contained in:
parent
75af359154
commit
5cc8013341
@ -1,9 +1,9 @@
|
|||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BattleScene from "../../battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { hasTouchscreen } from "../../touch-controls";
|
import { hasTouchscreen } from "#app/touch-controls";
|
||||||
import { updateWindowType } from "../../ui/ui-theme";
|
import { updateWindowType } from "#app/ui/ui-theme";
|
||||||
import { CandyUpgradeNotificationChangedEvent } from "../../events/battle-scene";
|
import { CandyUpgradeNotificationChangedEvent } from "#app/events/battle-scene";
|
||||||
import SettingsUiHandler from "#app/ui/settings/settings-ui-handler";
|
import SettingsUiHandler from "#app/ui/settings/settings-ui-handler";
|
||||||
import { EaseType } from "#enums/ease-type";
|
import { EaseType } from "#enums/ease-type";
|
||||||
import { MoneyFormat } from "#enums/money-format";
|
import { MoneyFormat } from "#enums/money-format";
|
||||||
@ -44,6 +44,7 @@ const OFF_ON: SettingOption[] = [
|
|||||||
label: i18next.t("settings:on")
|
label: i18next.t("settings:on")
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const AUTO_DISABLED: SettingOption[] = [
|
const AUTO_DISABLED: SettingOption[] = [
|
||||||
{
|
{
|
||||||
value: "Auto",
|
value: "Auto",
|
||||||
@ -55,6 +56,19 @@ const AUTO_DISABLED: SettingOption[] = [
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const TOUCH_CONTROLS_OPTIONS: SettingOption[] = [
|
||||||
|
{
|
||||||
|
value: "Auto",
|
||||||
|
label: i18next.t("settings:auto")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "Disabled",
|
||||||
|
label: i18next.t("settings:disabled"),
|
||||||
|
needConfirmation: true,
|
||||||
|
confirmationMessage: i18next.t("settings:confirmDisableTouch")
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
const SHOP_CURSOR_TARGET_OPTIONS: SettingOption[] = [
|
const SHOP_CURSOR_TARGET_OPTIONS: SettingOption[] = [
|
||||||
{
|
{
|
||||||
value: "Rewards",
|
value: "Rewards",
|
||||||
@ -100,7 +114,9 @@ export enum SettingType {
|
|||||||
|
|
||||||
type SettingOption = {
|
type SettingOption = {
|
||||||
value: string,
|
value: string,
|
||||||
label: string
|
label: string,
|
||||||
|
needConfirmation?: boolean,
|
||||||
|
confirmationMessage?: string
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Setting {
|
export interface Setting {
|
||||||
@ -344,13 +360,6 @@ export const Setting: Array<Setting> = [
|
|||||||
default: 1,
|
default: 1,
|
||||||
type: SettingType.GENERAL
|
type: SettingType.GENERAL
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: SettingKeys.Touch_Controls,
|
|
||||||
label: i18next.t("settings:touchControls"),
|
|
||||||
options: AUTO_DISABLED,
|
|
||||||
default: 0,
|
|
||||||
type: SettingType.GENERAL
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: SettingKeys.Vibration,
|
key: SettingKeys.Vibration,
|
||||||
label: i18next.t("settings:vibrations"),
|
label: i18next.t("settings:vibrations"),
|
||||||
@ -358,6 +367,28 @@ export const Setting: Array<Setting> = [
|
|||||||
default: 0,
|
default: 0,
|
||||||
type: SettingType.GENERAL
|
type: SettingType.GENERAL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: SettingKeys.Touch_Controls,
|
||||||
|
label: i18next.t("settings:touchControls"),
|
||||||
|
options: TOUCH_CONTROLS_OPTIONS,
|
||||||
|
default: 0,
|
||||||
|
type: SettingType.GENERAL,
|
||||||
|
isHidden: () => !hasTouchscreen()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: SettingKeys.Move_Touch_Controls,
|
||||||
|
label: i18next.t("settings:moveTouchControls"),
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: "Configure",
|
||||||
|
label: i18next.t("settings:change")
|
||||||
|
}
|
||||||
|
],
|
||||||
|
default: 0,
|
||||||
|
type: SettingType.GENERAL,
|
||||||
|
activatable: true,
|
||||||
|
isHidden: () => !hasTouchscreen()
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: SettingKeys.Language,
|
key: SettingKeys.Language,
|
||||||
label: i18next.t("settings:language"),
|
label: i18next.t("settings:language"),
|
||||||
@ -643,20 +674,6 @@ export const Setting: Array<Setting> = [
|
|||||||
type: SettingType.AUDIO,
|
type: SettingType.AUDIO,
|
||||||
requireReload: true
|
requireReload: true
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: SettingKeys.Move_Touch_Controls,
|
|
||||||
label: i18next.t("settings:moveTouchControls"),
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: "Configure",
|
|
||||||
label: i18next.t("settings:change")
|
|
||||||
}
|
|
||||||
],
|
|
||||||
default: 0,
|
|
||||||
type: SettingType.GENERAL,
|
|
||||||
activatable: true,
|
|
||||||
isHidden: () => !hasTouchscreen()
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: SettingKeys.Shop_Cursor_Target,
|
key: SettingKeys.Shop_Cursor_Target,
|
||||||
label: i18next.t("settings:shopCursorTarget"),
|
label: i18next.t("settings:shopCursorTarget"),
|
||||||
@ -849,7 +866,7 @@ export function setSetting(scene: BattleScene, setting: string, value: integer):
|
|||||||
if (scene.ui) {
|
if (scene.ui) {
|
||||||
const cancelHandler = () => {
|
const cancelHandler = () => {
|
||||||
scene.ui.revertMode();
|
scene.ui.revertMode();
|
||||||
(scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(0, 0, true);
|
(scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true);
|
||||||
};
|
};
|
||||||
const changeLocaleHandler = (locale: string): boolean => {
|
const changeLocaleHandler = (locale: string): boolean => {
|
||||||
try {
|
try {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import BattleScene from "#app/battle-scene";
|
import BattleScene from "#app/battle-scene";
|
||||||
import { hasTouchscreen, isMobile } from "#app/touch-controls";
|
|
||||||
import { TextStyle, addTextObject } from "#app/ui/text";
|
import { TextStyle, addTextObject } from "#app/ui/text";
|
||||||
import { Mode } from "#app/ui/ui";
|
import { Mode } from "#app/ui/ui";
|
||||||
import UiHandler from "#app/ui/ui-handler";
|
import MessageUiHandler from "#app/ui/message-ui-handler";
|
||||||
import { addWindow } from "#app/ui/ui-theme";
|
import { addWindow } from "#app/ui/ui-theme";
|
||||||
import { ScrollBar } from "#app/ui/scroll-bar";
|
import { ScrollBar } from "#app/ui/scroll-bar";
|
||||||
import { Button } from "#enums/buttons";
|
import { Button } from "#enums/buttons";
|
||||||
@ -15,9 +14,10 @@ import i18next from "i18next";
|
|||||||
/**
|
/**
|
||||||
* Abstract class for handling UI elements related to settings.
|
* Abstract class for handling UI elements related to settings.
|
||||||
*/
|
*/
|
||||||
export default class AbstractSettingsUiHandler extends UiHandler {
|
export default class AbstractSettingsUiHandler extends MessageUiHandler {
|
||||||
private settingsContainer: Phaser.GameObjects.Container;
|
private settingsContainer: Phaser.GameObjects.Container;
|
||||||
private optionsContainer: Phaser.GameObjects.Container;
|
private optionsContainer: Phaser.GameObjects.Container;
|
||||||
|
private messageBoxContainer: Phaser.GameObjects.Container;
|
||||||
private navigationContainer: NavigationMenu;
|
private navigationContainer: NavigationMenu;
|
||||||
|
|
||||||
private scrollCursor: number;
|
private scrollCursor: number;
|
||||||
@ -135,6 +135,23 @@ export default class AbstractSettingsUiHandler extends UiHandler {
|
|||||||
this.scrollBar = new ScrollBar(this.scene, this.optionsBg.width - 9, this.optionsBg.y + 5, 4, this.optionsBg.height - 11, this.rowsToDisplay);
|
this.scrollBar = new ScrollBar(this.scene, this.optionsBg.width - 9, this.optionsBg.y + 5, 4, this.optionsBg.height - 11, this.rowsToDisplay);
|
||||||
this.scrollBar.setTotalRows(this.settings.length);
|
this.scrollBar.setTotalRows(this.settings.length);
|
||||||
|
|
||||||
|
// Two-lines message box
|
||||||
|
this.messageBoxContainer = this.scene.add.container(0, this.scene.scaledCanvas.height);
|
||||||
|
this.messageBoxContainer.setName("settings-message-box");
|
||||||
|
this.messageBoxContainer.setVisible(false);
|
||||||
|
|
||||||
|
const settingsMessageBox = addWindow(this.scene, 0, -1, this.scene.scaledCanvas.width - 2, 48);
|
||||||
|
settingsMessageBox.setOrigin(0, 1);
|
||||||
|
this.messageBoxContainer.add(settingsMessageBox);
|
||||||
|
|
||||||
|
const messageText = addTextObject(this.scene, 8, -40, "", TextStyle.WINDOW, { maxLines: 2 });
|
||||||
|
messageText.setWordWrapWidth(this.scene.game.canvas.width - 60);
|
||||||
|
messageText.setName("settings-message");
|
||||||
|
messageText.setOrigin(0, 0);
|
||||||
|
|
||||||
|
this.messageBoxContainer.add(messageText);
|
||||||
|
this.message = messageText;
|
||||||
|
|
||||||
this.settingsContainer.add(this.optionsBg);
|
this.settingsContainer.add(this.optionsBg);
|
||||||
this.settingsContainer.add(this.scrollBar);
|
this.settingsContainer.add(this.scrollBar);
|
||||||
this.settingsContainer.add(this.navigationContainer);
|
this.settingsContainer.add(this.navigationContainer);
|
||||||
@ -144,6 +161,7 @@ export default class AbstractSettingsUiHandler extends UiHandler {
|
|||||||
this.settingsContainer.add(iconCancel);
|
this.settingsContainer.add(iconCancel);
|
||||||
this.settingsContainer.add(actionText);
|
this.settingsContainer.add(actionText);
|
||||||
this.settingsContainer.add(cancelText);
|
this.settingsContainer.add(cancelText);
|
||||||
|
this.settingsContainer.add(this.messageBoxContainer);
|
||||||
|
|
||||||
ui.add(this.settingsContainer);
|
ui.add(this.settingsContainer);
|
||||||
|
|
||||||
@ -326,18 +344,16 @@ export default class AbstractSettingsUiHandler extends UiHandler {
|
|||||||
/**
|
/**
|
||||||
* Set the option cursor to the specified position.
|
* Set the option cursor to the specified position.
|
||||||
*
|
*
|
||||||
* @param settingIndex - The index of the setting.
|
* @param settingIndex - The index of the setting or -1 to change the current setting
|
||||||
* @param cursor - The cursor position to set.
|
* @param cursor - The cursor position to set.
|
||||||
* @param save - Whether to save the setting to local storage.
|
* @param save - Whether to save the setting to local storage.
|
||||||
* @returns `true` if the option cursor was set successfully.
|
* @returns `true` if the option cursor was set successfully.
|
||||||
*/
|
*/
|
||||||
setOptionCursor(settingIndex: number, cursor: number, save?: boolean): boolean {
|
setOptionCursor(settingIndex: number, cursor: number, save?: boolean): boolean {
|
||||||
const setting = this.settings[settingIndex];
|
if (settingIndex === -1) {
|
||||||
|
settingIndex = this.cursor + this.scrollCursor;
|
||||||
if (setting.key === SettingKeys.Touch_Controls && cursor && hasTouchscreen() && isMobile()) {
|
|
||||||
this.getUi().playError();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
const setting = this.settings[settingIndex];
|
||||||
|
|
||||||
const lastCursor = this.optionCursors[settingIndex];
|
const lastCursor = this.optionCursors[settingIndex];
|
||||||
|
|
||||||
@ -352,9 +368,33 @@ export default class AbstractSettingsUiHandler extends UiHandler {
|
|||||||
newValueLabel.setShadowColor(this.getTextColor(TextStyle.SETTINGS_SELECTED, true));
|
newValueLabel.setShadowColor(this.getTextColor(TextStyle.SETTINGS_SELECTED, true));
|
||||||
|
|
||||||
if (save) {
|
if (save) {
|
||||||
this.scene.gameData.saveSetting(setting.key, cursor);
|
const saveSetting = () => {
|
||||||
if (this.reloadSettings.includes(setting)) {
|
this.scene.gameData.saveSetting(setting.key, cursor);
|
||||||
this.reloadRequired = true;
|
if (setting.requireReload) {
|
||||||
|
this.reloadRequired = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// For settings that ask for confirmation, display confirmation message and a Yes/No prompt before saving the setting
|
||||||
|
if (setting.options[cursor].needConfirmation) {
|
||||||
|
const confirmUpdateSetting = () => {
|
||||||
|
this.scene.ui.revertMode();
|
||||||
|
this.showText("");
|
||||||
|
saveSetting();
|
||||||
|
};
|
||||||
|
const cancelUpdateSetting = () => {
|
||||||
|
this.scene.ui.revertMode();
|
||||||
|
this.showText("");
|
||||||
|
// Put the cursor back to its previous position without saving or asking for confirmation again
|
||||||
|
this.setOptionCursor(settingIndex, lastCursor, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmationMessage = setting.options[cursor].confirmationMessage ?? i18next.t("settings:defaultConfirmMessage");
|
||||||
|
this.scene.ui.showText(confirmationMessage, null, () => {
|
||||||
|
this.scene.ui.setOverlayMode(Mode.CONFIRM, confirmUpdateSetting, cancelUpdateSetting, null, null, 1, 750);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
saveSetting();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,4 +461,9 @@ export default class AbstractSettingsUiHandler extends UiHandler {
|
|||||||
}
|
}
|
||||||
this.cursorObj = null;
|
this.cursorObj = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
|
||||||
|
this.messageBoxContainer.setVisible(!!text?.length);
|
||||||
|
super.showText(text, delay, callback, callbackDelay, prompt, promptDelay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user