Make Controller shortcuts settings controller-friendly

This commit is contained in:
redphx 2024-07-16 17:59:21 +07:00
parent b66cb448ec
commit 2a0af5d0ab
4 changed files with 49 additions and 27 deletions

View File

@ -3,7 +3,7 @@
align-items: center; align-items: center;
select { select {
display: none; display: none !important;
} }
> div, button.bx-select-value { > div, button.bx-select-value {
@ -16,6 +16,7 @@
color: #000; color: #000;
border-radius: 4px; border-radius: 4px;
padding: 2px 8px; padding: 2px 8px;
flex: 1;
} }
> div { > div {

View File

@ -11,6 +11,7 @@ import { PrefKey, getPref } from "@utils/preferences";
import { SoundShortcut } from "./shortcuts/shortcut-sound"; import { SoundShortcut } from "./shortcuts/shortcut-sound";
import { BxEvent } from "@/utils/bx-event"; import { BxEvent } from "@/utils/bx-event";
import { AppInterface } from "@/utils/global"; import { AppInterface } from "@/utils/global";
import { BxSelectElement } from "@/web-components/bx-select";
enum ShortcutAction { enum ShortcutAction {
STREAM_SCREENSHOT_CAPTURE = 'stream-screenshot-capture', STREAM_SCREENSHOT_CAPTURE = 'stream-screenshot-capture',
@ -211,6 +212,8 @@ export class ControllerShortcut {
} }
static renderSettings() { static renderSettings() {
const PREF_CONTROLLER_FRIENDLY_UI = getPref(PrefKey.UI_CONTROLLER_FRIENDLY);
// Read actions from localStorage // Read actions from localStorage
ControllerShortcut.#ACTIONS = JSON.parse(window.localStorage.getItem(ControllerShortcut.#STORAGE_KEY) || '{}'); ControllerShortcut.#ACTIONS = JSON.parse(window.localStorage.getItem(ControllerShortcut.#STORAGE_KEY) || '{}');
@ -287,23 +290,23 @@ export class ControllerShortcut {
} }
let $remap: HTMLElement; let $remap: HTMLElement;
let $selectProfile: HTMLSelectElement; const $selectProfile = CE<HTMLSelectElement>('select', {class: 'bx-shortcut-profile', autocomplete: 'off'});
const $container = CE('div', {'data-has-gamepad': 'false'}, const $container = CE('div', {'data-has-gamepad': 'false'},
CE('div', {}, CE('div', {},
CE('p', {'class': 'bx-shortcut-note'}, t('controller-shortcuts-connect-note')), CE('p', {class: 'bx-shortcut-note'}, t('controller-shortcuts-connect-note')),
), ),
$remap = CE('div', {}, $remap = CE('div', {},
$selectProfile = CE('select', {'class': 'bx-shortcut-profile', autocomplete: 'off'}), PREF_CONTROLLER_FRIENDLY_UI ? CE('div', {'data-focus-container': 'true'}, BxSelectElement.wrap($selectProfile)) : $selectProfile,
CE('p', {'class': 'bx-shortcut-note'}, CE('p', {class: 'bx-shortcut-note'},
CE('span', {'class': 'bx-prompt'}, PrompFont.HOME), CE('span', {class: 'bx-prompt'}, PrompFont.HOME),
': ' + t('controller-shortcuts-xbox-note'), ': ' + t('controller-shortcuts-xbox-note'),
), ),
), ),
); );
$selectProfile.addEventListener('change', e => { $selectProfile.addEventListener('input', e => {
ControllerShortcut.#switchProfile($selectProfile.value); ControllerShortcut.#switchProfile($selectProfile.value);
}); });
@ -314,6 +317,7 @@ export class ControllerShortcut {
const button: unknown = $target.dataset.button; const button: unknown = $target.dataset.button;
const action = $target.value as ShortcutAction; const action = $target.value as ShortcutAction;
if (!PREF_CONTROLLER_FRIENDLY_UI) {
const $fakeSelect = $target.previousElementSibling! as HTMLSelectElement; const $fakeSelect = $target.previousElementSibling! as HTMLSelectElement;
let fakeText = '---'; let fakeText = '---';
if (action) { if (action) {
@ -322,30 +326,42 @@ export class ControllerShortcut {
fakeText = $optGroup.label + ' ' + $selectedOption.text; fakeText = $optGroup.label + ' ' + $selectedOption.text;
} }
($fakeSelect.firstElementChild as HTMLOptionElement).text = fakeText; ($fakeSelect.firstElementChild as HTMLOptionElement).text = fakeText;
}
!(e as any).ignoreOnChange && ControllerShortcut.#updateAction(profile, button as GamepadKey, action); !(e as any).ignoreOnChange && ControllerShortcut.#updateAction(profile, button as GamepadKey, action);
}; };
// @ts-ignore // @ts-ignore
for (const [button, prompt] of buttons) { for (const [button, prompt] of buttons) {
const $row = CE('div', {'class': 'bx-shortcut-row'}); const $row = CE('div', {
class: 'bx-shortcut-row',
'data-focus-container': 'true',
});
const $label = CE('label', {'class': 'bx-prompt'}, `${PrompFont.HOME} + ${prompt}`); const $label = CE('label', {class: 'bx-prompt'}, `${PrompFont.HOME} + ${prompt}`);
const $div = CE('div', {'class': 'bx-shortcut-actions'}); const $div = CE('div', {class: 'bx-shortcut-actions'});
if (!PREF_CONTROLLER_FRIENDLY_UI) {
const $fakeSelect = CE<HTMLSelectElement>('select', {autocomplete: 'off'}, const $fakeSelect = CE<HTMLSelectElement>('select', {autocomplete: 'off'},
CE('option', {}, '---'), CE('option', {}, '---'),
); );
$div.appendChild($fakeSelect); $div.appendChild($fakeSelect);
}
const $select = $baseSelect.cloneNode(true) as HTMLSelectElement; const $select = $baseSelect.cloneNode(true) as HTMLSelectElement;
$select.dataset.button = button.toString(); $select.dataset.button = button.toString();
$select.addEventListener('change', onActionChanged); $select.addEventListener('input', onActionChanged);
ControllerShortcut.#$selectActions[button] = $select; ControllerShortcut.#$selectActions[button] = $select;
if (PREF_CONTROLLER_FRIENDLY_UI) {
$div.appendChild(BxSelectElement.wrap($select));
} else {
$div.appendChild($select); $div.appendChild($select);
}
$row.appendChild($label); $row.appendChild($label);
$row.appendChild($div); $row.appendChild($div);

View File

@ -329,7 +329,7 @@ export class StreamSettings {
// Current element is setting -> Find the next one // Current element is setting -> Find the next one
// Find parent // Find parent
let $parent = $focusing.closest('.bx-stream-settings-row') || $focusing.closest('h2'); let $parent = $focusing.closest('[data-focus-container]');
if (!$parent) { if (!$parent) {
return; return;
@ -507,7 +507,7 @@ export class StreamSettings {
continue; continue;
} }
$group.appendChild(CE('h2', {}, $group.appendChild(CE('h2', {'data-focus-container': 'true'},
CE('span', {}, settingGroup.label), CE('span', {}, settingGroup.label),
settingGroup.help_url && createButton({ settingGroup.help_url && createButton({
icon: BxIcon.QUESTION, icon: BxIcon.QUESTION,
@ -555,7 +555,11 @@ export class StreamSettings {
const label = Preferences.SETTINGS[pref as PrefKey]?.label || setting.label; const label = Preferences.SETTINGS[pref as PrefKey]?.label || setting.label;
const note = Preferences.SETTINGS[pref as PrefKey]?.note || setting.note; const note = Preferences.SETTINGS[pref as PrefKey]?.note || setting.note;
const $content = CE('div', {'class': 'bx-stream-settings-row', 'data-type': settingGroup.group}, const $content = CE('div', {
class: 'bx-stream-settings-row',
'data-type': settingGroup.group,
'data-focus-container': 'true',
},
CE('label', {for: `bx_setting_${pref}`}, CE('label', {for: `bx_setting_${pref}`},
label, label,
note && CE('div', {'class': 'bx-stream-settings-dialog-note'}, note), note && CE('div', {'class': 'bx-stream-settings-dialog-note'}, note),

View File

@ -54,7 +54,8 @@ export class BxSelectElement {
} }
const getOptionAtIndex = (index: number): HTMLOptionElement | undefined => { const getOptionAtIndex = (index: number): HTMLOptionElement | undefined => {
return $select.querySelector(`option:nth-of-type(${visibleIndex + 1})`) as HTMLOptionElement; const options = Array.from($select.querySelectorAll('option'));
return options[index];
} }
const render = () => { const render = () => {