Render controller customization summary

This commit is contained in:
redphx 2024-12-23 21:14:39 +07:00
parent 68d9e7368c
commit 6d1e06dbfe
5 changed files with 122 additions and 27 deletions

View File

@ -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;
}
}

View File

@ -34,6 +34,9 @@ export abstract class BaseProfileManagerDialog<T extends PresetRecord> extends N
} }
protected abstract switchPreset(id: number): void; protected abstract switchPreset(id: number): void;
async renderSummary(presetId: number): Promise<HTMLElement | DocumentFragment | null> {
return null;
}
protected updateButtonStates() { protected updateButtonStates() {
const isDefaultPreset = this.currentPresetId === null || this.currentPresetId <= 0; const isDefaultPreset = this.currentPresetId === null || this.currentPresetId <= 0;

View File

@ -15,6 +15,7 @@ import { NavigationDirection, type NavigationElement } from "../navigation-dialo
import { setNearby } from "@/utils/navigation-utils"; import { setNearby } from "@/utils/navigation-utils";
import type { DualNumberStepperParams } from "@/types/setting-definition"; import type { DualNumberStepperParams } from "@/types/setting-definition";
import { BxNumberStepper } from "@/web-components/bx-number-stepper"; import { BxNumberStepper } from "@/web-components/bx-number-stepper";
import { getGamepadPrompt } from "@/utils/gamepad";
export class ControllerCustomizationsManagerDialog extends BaseProfileManagerDialog<ControllerCustomizationPresetRecord> { export class ControllerCustomizationsManagerDialog extends BaseProfileManagerDialog<ControllerCustomizationPresetRecord> {
private static instance: ControllerCustomizationsManagerDialog; private static instance: ControllerCustomizationsManagerDialog;
@ -367,4 +368,46 @@ export class ControllerCustomizationsManagerDialog extends BaseProfileManagerDia
preset.data = newData; preset.data = newData;
this.presetsDb.updatePreset(preset); 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<keyof typeof presetData.settings>;
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;
}
} }

View File

@ -19,11 +19,13 @@ export class ControllerExtraSettings extends HTMLElement {
$selectControllers!: BxSelectElement; $selectControllers!: BxSelectElement;
$selectShortcuts!: BxSelectElement; $selectShortcuts!: BxSelectElement;
$selectCustomization!: BxSelectElement; $selectCustomization!: BxSelectElement;
$summaryCustomization!: HTMLElement;
updateLayout!: () => void; updateLayout!: typeof ControllerExtraSettings['updateLayout'];
switchController!: (id: string) => void; switchController!: typeof ControllerExtraSettings['switchController'];
getCurrentControllerId!: () => string | null; getCurrentControllerId!: typeof ControllerExtraSettings['getCurrentControllerId'];
saveSettings!: () => void; saveSettings!: typeof ControllerExtraSettings['saveSettings'];
updateCustomizationSummary!: typeof ControllerExtraSettings['updateCustomizationSummary'];
static renderSettings(this: SettingsDialog): HTMLElement { static renderSettings(this: SettingsDialog): HTMLElement {
const $container = CE('label', { const $container = CE('label', {
@ -52,9 +54,40 @@ export class ControllerExtraSettings extends HTMLElement {
const $selectCustomization = BxSelectElement.create(CE('select', { const $selectCustomization = BxSelectElement.create(CE('select', {
autocomplete: 'off', 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( $container.append(
CE('span', false, t('no-controllers-connected')), CE('span', false, t('no-controllers-connected')),
CE('div', { class: 'bx-controller-extra-wrapper' }, CE('div', { class: 'bx-controller-extra-wrapper' },
@ -80,27 +113,7 @@ export class ControllerExtraSettings extends HTMLElement {
{ multiLines: true }, { multiLines: true },
), ),
createSettingRow( $rowCustomization,
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')),
},
),
), ),
), ),
); );
@ -123,7 +136,17 @@ export class ControllerExtraSettings extends HTMLElement {
return $container; 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.controllerIds = getUniqueGamepadNames();
this.dataset.hasGamepad = (this.controllerIds.length > 0).toString(); this.dataset.hasGamepad = (this.controllerIds.length > 0).toString();
@ -173,6 +196,9 @@ export class ControllerExtraSettings extends HTMLElement {
// Update UI // Update UI
this.$selectShortcuts.value = controllerSettings.shortcutPresetId.toString(); this.$selectShortcuts.value = controllerSettings.shortcutPresetId.toString();
this.$selectCustomization.value = controllerSettings.customizationPresetId.toString(); this.$selectCustomization.value = controllerSettings.customizationPresetId.toString();
// Update summary
ControllerExtraSettings.updateCustomizationSummary.call(this);
} }
private static getCurrentControllerId(this: ControllerExtraSettings) { private static getCurrentControllerId(this: ControllerExtraSettings) {

View File

@ -4,6 +4,7 @@ import { Toast } from "@utils/toast";
import { BxLogger } from "@utils/bx-logger"; import { BxLogger } from "@utils/bx-logger";
import { PrefKey } from "@/enums/pref-keys"; import { PrefKey } from "@/enums/pref-keys";
import { getPref } from "./settings-storages/global-settings-storage"; import { getPref } from "./settings-storages/global-settings-storage";
import { GamepadKeyName, type GamepadKey } from "@/enums/gamepad";
// Show a toast when connecting/disconecting controller // Show a toast when connecting/disconecting controller
export function showGamepadToast(gamepad: Gamepad) { export function showGamepadToast(gamepad: Gamepad) {
@ -90,3 +91,7 @@ export function generateVirtualControllerMapping(override: {}={}) {
return Object.assign({}, mapping, override); return Object.assign({}, mapping, override);
} }
export function getGamepadPrompt(gamepadKey: GamepadKey): string {
return GamepadKeyName[gamepadKey][1];
}