From 91b32132d071f51248695137f5255ebe9e1eddf3 Mon Sep 17 00:00:00 2001 From: Leo Kim <47556641+KimJeongSun@users.noreply.github.com> Date: Tue, 6 Aug 2024 00:42:15 +0900 Subject: [PATCH] [Bug,Enhancement] Fix and improve Starter selector UI (#3340) * apply offset to all hybrid filter * make dropDownType to public for offsetHybridFilter function * refactoring defaultSettings to additional suport default cursor. * fix to remember last cursor on hover mode * remove unnecessary reset code * fix sort reset function * update resetFilter function * update requested changes * remove log msg * fix checking default on sort * refactoring hasDefaultValues function for readability * fix lastdir bug --- src/ui/dropdown.ts | 99 +++++++++++++++-------------- src/ui/filter-bar.ts | 14 ++-- src/ui/starter-select-ui-handler.ts | 23 +++---- 3 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/ui/dropdown.ts b/src/ui/dropdown.ts index 4338e11e0c6..80935d16a71 100644 --- a/src/ui/dropdown.ts +++ b/src/ui/dropdown.ts @@ -27,10 +27,10 @@ export class DropDownLabel { public text: string; public sprite?: Phaser.GameObjects.Sprite; - constructor(label: string, sprite?: Phaser.GameObjects.Sprite, state: DropDownState = DropDownState.ON) { + constructor(label: string, sprite?: Phaser.GameObjects.Sprite, state: DropDownState = DropDownState.OFF) { this.text = label || ""; this.sprite = sprite; - this.state = state || DropDownState.ON; + this.state = state; } } @@ -262,12 +262,13 @@ export class DropDown extends Phaser.GameObjects.Container { public options: DropDownOption[]; private window: Phaser.GameObjects.NineSlice; private cursorObj: Phaser.GameObjects.Image; - private dropDownType: DropDownType = DropDownType.MULTI; + public dropDownType: DropDownType = DropDownType.MULTI; public cursor: number = 0; + private lastCursor: number = -1; public defaultCursor: number = 0; private onChange: () => void; private lastDir: SortDirection = SortDirection.ASC; - private defaultValues: any[]; + private defaultSettings: any[]; constructor(scene: BattleScene, x: number, y: number, options: DropDownOption[], onChange: () => void, type: DropDownType = DropDownType.MULTI, optionSpacing: number = 2) { const windowPadding = 5; @@ -292,7 +293,7 @@ export class DropDown extends Phaser.GameObjects.Container { this.options.unshift(new DropDownOption(scene, "ALL", new DropDownLabel(i18next.t("filterBar:all"), undefined, this.checkForAllOn() ? DropDownState.ON : DropDownState.OFF))); } - this.defaultValues = this.getVals(); + this.defaultSettings = this.getSettings(); // Place ui elements in the correct spot options.forEach((option, index) => { @@ -339,8 +340,8 @@ export class DropDown extends Phaser.GameObjects.Container { resetCursor(): boolean { // If we are an hybrid dropdown in "hover" mode, don't move the cursor back to 0 - if (this.dropDownType === DropDownType.HYBRID && this.checkForAllOff() && this.cursor > 0) { - return false; + if (this.dropDownType === DropDownType.HYBRID && this.checkForAllOff()) { + return this.setCursor(this.lastCursor); } return this.setCursor(this.defaultCursor); } @@ -361,6 +362,7 @@ export class DropDown extends Phaser.GameObjects.Container { this.cursorObj.setVisible(true); // If hydrid type, we need to update the filters when going up/down in the list if (this.dropDownType === DropDownType.HYBRID) { + this.lastCursor = cursor; this.onChange(); } } @@ -457,23 +459,43 @@ export class DropDown extends Phaser.GameObjects.Container { } } + /** + * Get the current selected settings dictionary for each option + * @returns an array of dictionaries with the current state of each option + * - the settings dictionary is like this { val: any, state: DropDownState, cursor: boolean, dir: SortDirection } + */ + private getSettings(): any[] { + const settings = []; + for (let i = 0; i < this.options.length; i++) { + settings.push({ val: this.options[i].val, state: this.options[i].state , cursor: (this.cursor === i), dir: this.options[i].dir }); + } + return settings; + } + /** * Check whether the values of all options are the same as the default ones * @returns true if they are the same, false otherwise */ public hasDefaultValues(): boolean { - const currentValues = this.getVals(); + const currentValues = this.getSettings(); + + const compareValues = (keys: string[]): boolean => { + return currentValues.length === this.defaultSettings.length && + currentValues.every((value, index) => + keys.every(key => value[key] === this.defaultSettings[index][key]) + ); + }; switch (this.dropDownType) { case DropDownType.MULTI: - case DropDownType.HYBRID: - return currentValues.length === this.defaultValues.length && currentValues.every((value, index) => value === this.defaultValues[index]); - case DropDownType.RADIAL: - return currentValues.every((value, index) => value["val"] === this.defaultValues[index]["val"] && value["state"] === this.defaultValues[index]["state"]); + return compareValues(["val", "state"]); + + case DropDownType.HYBRID: + return compareValues(["val", "state", "cursor"]); case DropDownType.SINGLE: - return currentValues[0]["dir"] === this.defaultValues[0]["dir"] && currentValues[0]["val"] === this.defaultValues[0]["val"]; + return compareValues(["val", "state", "dir"]); default: return false; @@ -484,46 +506,29 @@ export class DropDown extends Phaser.GameObjects.Container { * Set all values to their default state */ public resetToDefault(): void { - this.setCursor(this.defaultCursor); + if (this.defaultSettings.length > 0) { + this.setCursor(this.defaultCursor); + this.lastDir = SortDirection.ASC; - for (let i = 0; i < this.options.length; i++) { - const option = this.options[i]; - // reset values - switch (this.dropDownType) { - case DropDownType.HYBRID: - case DropDownType.MULTI: - if (this.defaultValues.includes(option.val)) { - option.setOptionState(DropDownState.ON); + for (let i = 0; i < this.options.length; i++) { + // reset values with the defaultValues + if (this.dropDownType === DropDownType.SINGLE) { + if (this.defaultSettings[i].state === DropDownState.OFF) { + this.options[i].setOptionState(DropDownState.OFF); + this.options[i].setDirection(SortDirection.ASC); + this.options[i].toggle.setVisible(false); + } else { + this.options[i].setOptionState(DropDownState.ON); + this.options[i].setDirection(SortDirection.ASC); + this.options[i].toggle.setVisible(true); + } } else { - option.setOptionState(DropDownState.OFF); - } - break; - case DropDownType.RADIAL: - const targetValue = this.defaultValues.find(value => value.val === option.val); - option.setOptionState(targetValue.state); - break; - case DropDownType.SINGLE: - if (option.val === this.defaultValues[0].val) { - if (option.state !== DropDownState.ON) { - this.toggleOptionState(i); - } - if (option.dir !== this.defaultValues[0].dir) { - this.toggleOptionState(i); + if (this.defaultSettings[i]) { + this.options[i].setOptionState(this.defaultSettings[i]["state"]); } } - break; } } - - // Select or unselect "ALL" button if applicable - if (this.dropDownType === DropDownType.MULTI || this.dropDownType === DropDownType.HYBRID) { - if (this.checkForAllOn()) { - this.options[0].setOptionState(DropDownState.ON); - } else { - this.options[0].setOptionState(DropDownState.OFF); - } - } - } /** diff --git a/src/ui/filter-bar.ts b/src/ui/filter-bar.ts index e163284bad3..072d258085b 100644 --- a/src/ui/filter-bar.ts +++ b/src/ui/filter-bar.ts @@ -1,5 +1,5 @@ import BattleScene from "#app/battle-scene.js"; -import { DropDown } from "./dropdown"; +import { DropDown, DropDownType } from "./dropdown"; import { StarterContainer } from "./starter-container"; import { addTextObject, getTextColor, TextStyle } from "./text"; import { UiTheme } from "#enums/ui-theme"; @@ -120,11 +120,13 @@ export class FilterBar extends Phaser.GameObjects.Container { /** * Move the leftmost dropdown to the left of the FilterBar instead of below it */ - offsetFirstFilter(): void { - if (this.dropDowns[0]) { - this.dropDowns[0].autoSize(); - this.dropDowns[0].x -= this.dropDowns[0].getWidth(); - this.dropDowns[0].y = 0; + offsetHybridFilters(): void { + for (let i=0; i