From 6d1e06dbfed22a04d2882c9f0f116bca1ae460a6 Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Mon, 23 Dec 2024 21:14:39 +0700 Subject: [PATCH] Render controller customization summary --- src/assets/css/controller.styl | 18 +++++ .../base-profile-manager-dialog.ts | 3 + ...ontroller-customizations-manager-dialog.ts | 43 ++++++++++ .../ui/dialog/settings/controller-extra.ts | 80 ++++++++++++------- src/utils/gamepad.ts | 5 ++ 5 files changed, 122 insertions(+), 27 deletions(-) diff --git a/src/assets/css/controller.styl b/src/assets/css/controller.styl index e12089d..bd00a57 100644 --- a/src/assets/css/controller.styl +++ b/src/assets/css/controller.styl @@ -69,3 +69,21 @@ } } } + +.bx-controller-customization-summary { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 8px; + margin-top: 10px; + + span { + font-family: var(--bx-promptfont); + font-size: 24px; + border-radius: 6px; + background: #131313; + color: #fff; + display: inline-block; + padding: 2px; + text-align: center; + } +} diff --git a/src/modules/ui/dialog/profile-manger/base-profile-manager-dialog.ts b/src/modules/ui/dialog/profile-manger/base-profile-manager-dialog.ts index e5e13f3..95a36c6 100755 --- a/src/modules/ui/dialog/profile-manger/base-profile-manager-dialog.ts +++ b/src/modules/ui/dialog/profile-manger/base-profile-manager-dialog.ts @@ -34,6 +34,9 @@ export abstract class BaseProfileManagerDialog extends N } protected abstract switchPreset(id: number): void; + async renderSummary(presetId: number): Promise { + return null; + } protected updateButtonStates() { const isDefaultPreset = this.currentPresetId === null || this.currentPresetId <= 0; diff --git a/src/modules/ui/dialog/profile-manger/controller-customizations-manager-dialog.ts b/src/modules/ui/dialog/profile-manger/controller-customizations-manager-dialog.ts index f5b9e3b..2ecfe24 100644 --- a/src/modules/ui/dialog/profile-manger/controller-customizations-manager-dialog.ts +++ b/src/modules/ui/dialog/profile-manger/controller-customizations-manager-dialog.ts @@ -15,6 +15,7 @@ import { NavigationDirection, type NavigationElement } from "../navigation-dialo import { setNearby } from "@/utils/navigation-utils"; import type { DualNumberStepperParams } from "@/types/setting-definition"; import { BxNumberStepper } from "@/web-components/bx-number-stepper"; +import { getGamepadPrompt } from "@/utils/gamepad"; export class ControllerCustomizationsManagerDialog extends BaseProfileManagerDialog { private static instance: ControllerCustomizationsManagerDialog; @@ -367,4 +368,46 @@ export class ControllerCustomizationsManagerDialog extends BaseProfileManagerDia preset.data = newData; this.presetsDb.updatePreset(preset); } + + async renderSummary(presetId: number) { + const preset = await this.presetsDb.getPreset(presetId); + if (!preset) { + return null; + } + + const presetData = preset.data; + let $content: HTMLElement | undefined; + let showNote = false; + + if (Object.keys(presetData.mapping).length > 0) { + $content = CE('div', { class: 'bx-controller-customization-summary'}); + + for (const key in presetData.mapping) { + const gamepadKey = parseInt(key) as GamepadKey; + const mappedKey = presetData.mapping[gamepadKey]!; + + $content.append(CE('span', { class: 'bx-prompt' }, getGamepadPrompt(gamepadKey) + ' > ' + (mappedKey === false ? '🚫' : getGamepadPrompt(mappedKey)))); + } + + showNote = true; + } + + // Show note if it has settings other than 'vibrationIntensity' + const settingKeys = Object.keys(presetData.settings) as Array; + if (settingKeys.filter(key => key !== 'vibrationIntensity').length) { + showNote = true; + } + + const fragment = document.createDocumentFragment(); + if (showNote) { + const $note = CE('div', { class: 'bx-settings-dialog-note' }, 'ⓘ ' + t('slightly-increases-input-latency')); + fragment.appendChild($note); + } + + if ($content) { + fragment.appendChild($content); + } + + return fragment.childElementCount ? fragment : null; + } } diff --git a/src/modules/ui/dialog/settings/controller-extra.ts b/src/modules/ui/dialog/settings/controller-extra.ts index 033be99..e9afd8d 100755 --- a/src/modules/ui/dialog/settings/controller-extra.ts +++ b/src/modules/ui/dialog/settings/controller-extra.ts @@ -19,11 +19,13 @@ export class ControllerExtraSettings extends HTMLElement { $selectControllers!: BxSelectElement; $selectShortcuts!: BxSelectElement; $selectCustomization!: BxSelectElement; + $summaryCustomization!: HTMLElement; - updateLayout!: () => void; - switchController!: (id: string) => void; - getCurrentControllerId!: () => string | null; - saveSettings!: () => void; + updateLayout!: typeof ControllerExtraSettings['updateLayout']; + switchController!: typeof ControllerExtraSettings['switchController']; + getCurrentControllerId!: typeof ControllerExtraSettings['getCurrentControllerId']; + saveSettings!: typeof ControllerExtraSettings['saveSettings']; + updateCustomizationSummary!: typeof ControllerExtraSettings['updateCustomizationSummary']; static renderSettings(this: SettingsDialog): HTMLElement { const $container = CE('label', { @@ -52,9 +54,40 @@ export class ControllerExtraSettings extends HTMLElement { const $selectCustomization = BxSelectElement.create(CE('select', { autocomplete: 'off', - _on: { input: $container.saveSettings }, + _on: { + input: async () => { + // Update summary + ControllerExtraSettings.updateCustomizationSummary.call($container); + // Save settings + $container.saveSettings(); + }, + }, })); + const $rowCustomization = createSettingRow( + t('in-game-controller-customization'), + CE('div', { + class: 'bx-preset-row', + _nearby: { orientation: 'horizontal' }, + }, + $selectCustomization, + createButton({ + title: t('manage'), + icon: BxIcon.MANAGE, + style: ButtonStyle.FOCUSABLE | ButtonStyle.PRIMARY | ButtonStyle.AUTO_HEIGHT, + onClick: () => ControllerCustomizationsManagerDialog.getInstance().show({ + id: $container.$selectCustomization.value ? parseInt($container.$selectCustomization.value) : null, + }), + }), + ), + { + multiLines: true, + }, + ); + $rowCustomization.appendChild( + $container.$summaryCustomization = CE('div'), + ); + $container.append( CE('span', false, t('no-controllers-connected')), CE('div', { class: 'bx-controller-extra-wrapper' }, @@ -80,27 +113,7 @@ export class ControllerExtraSettings extends HTMLElement { { multiLines: true }, ), - createSettingRow( - t('in-game-controller-customization'), - CE('div', { - class: 'bx-preset-row', - _nearby: { orientation: 'horizontal' }, - }, - $selectCustomization, - createButton({ - title: t('manage'), - icon: BxIcon.MANAGE, - style: ButtonStyle.FOCUSABLE | ButtonStyle.PRIMARY | ButtonStyle.AUTO_HEIGHT, - onClick: () => ControllerCustomizationsManagerDialog.getInstance().show({ - id: $container.$selectCustomization.value ? parseInt($container.$selectCustomization.value) : null, - }), - }), - ), - { - multiLines: true, - $note: CE('div', { class: 'bx-settings-dialog-note' }, 'ⓘ ' + t('slightly-increases-input-latency')), - }, - ), + $rowCustomization, ), ), ); @@ -123,7 +136,17 @@ export class ControllerExtraSettings extends HTMLElement { return $container; } - private static async updateLayout(this: ControllerExtraSettings, e?: GamepadEvent) { + private static async updateCustomizationSummary(this: ControllerExtraSettings) { + const presetId = parseInt(this.$selectCustomization.value); + const $summaryContent = await ControllerCustomizationsManagerDialog.getInstance().renderSummary(presetId); + + removeChildElements(this.$summaryCustomization); + if ($summaryContent) { + this.$summaryCustomization.appendChild($summaryContent); + } + } + + private static async updateLayout(this: ControllerExtraSettings) { this.controllerIds = getUniqueGamepadNames(); this.dataset.hasGamepad = (this.controllerIds.length > 0).toString(); @@ -173,6 +196,9 @@ export class ControllerExtraSettings extends HTMLElement { // Update UI this.$selectShortcuts.value = controllerSettings.shortcutPresetId.toString(); this.$selectCustomization.value = controllerSettings.customizationPresetId.toString(); + + // Update summary + ControllerExtraSettings.updateCustomizationSummary.call(this); } private static getCurrentControllerId(this: ControllerExtraSettings) { diff --git a/src/utils/gamepad.ts b/src/utils/gamepad.ts index 3f46a67..7859790 100755 --- a/src/utils/gamepad.ts +++ b/src/utils/gamepad.ts @@ -4,6 +4,7 @@ import { Toast } from "@utils/toast"; import { BxLogger } from "@utils/bx-logger"; import { PrefKey } from "@/enums/pref-keys"; import { getPref } from "./settings-storages/global-settings-storage"; +import { GamepadKeyName, type GamepadKey } from "@/enums/gamepad"; // Show a toast when connecting/disconecting controller export function showGamepadToast(gamepad: Gamepad) { @@ -90,3 +91,7 @@ export function generateVirtualControllerMapping(override: {}={}) { return Object.assign({}, mapping, override); } + +export function getGamepadPrompt(gamepadKey: GamepadKey): string { + return GamepadKeyName[gamepadKey][1]; +}