mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-07 08:07:18 +02:00
Fix Virtual Controller Remapper's bug
This commit is contained in:
parent
b06dc6e219
commit
6440c91cdf
@ -1,4 +1,4 @@
|
|||||||
import { CE, createButton, ButtonStyle } from "@utils/html";
|
import { CE, createButton, ButtonStyle, removeChildElements } from "@utils/html";
|
||||||
import { t } from "@utils/translation";
|
import { t } from "@utils/translation";
|
||||||
import { Dialog } from "@modules/dialog";
|
import { Dialog } from "@modules/dialog";
|
||||||
import { KeyHelper } from "./key-helper";
|
import { KeyHelper } from "./key-helper";
|
||||||
@ -61,12 +61,10 @@ export class MkbRemapper {
|
|||||||
public static getInstance = () => MkbRemapper.instance ?? (MkbRemapper.instance = new MkbRemapper());
|
public static getInstance = () => MkbRemapper.instance ?? (MkbRemapper.instance = new MkbRemapper());
|
||||||
private readonly LOG_TAG = 'MkbRemapper';
|
private readonly LOG_TAG = 'MkbRemapper';
|
||||||
|
|
||||||
private STATE: MkbRemapperStates = {
|
private states: MkbRemapperStates = {
|
||||||
currentPresetId: 0,
|
currentPresetId: 0,
|
||||||
presets: {},
|
presets: {},
|
||||||
|
|
||||||
editingPresetData: null,
|
editingPresetData: null,
|
||||||
|
|
||||||
isEditing: false,
|
isEditing: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,7 +81,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
BxLogger.info(this.LOG_TAG, 'constructor()');
|
BxLogger.info(this.LOG_TAG, 'constructor()');
|
||||||
this.STATE.currentPresetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID);
|
this.states.currentPresetId = getPref(PrefKey.MKB_DEFAULT_PRESET_ID);
|
||||||
|
|
||||||
this.bindingDialog = new Dialog({
|
this.bindingDialog = new Dialog({
|
||||||
className: 'bx-binding-dialog',
|
className: 'bx-binding-dialog',
|
||||||
@ -117,7 +115,7 @@ export class MkbRemapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.STATE.editingPresetData!.mapping[buttonIndex][keySlot] = key.code;
|
this.states.editingPresetData!.mapping[buttonIndex][keySlot] = key.code;
|
||||||
$elm.textContent = key.name;
|
$elm.textContent = key.name;
|
||||||
$elm.dataset.keyCode = key.code;
|
$elm.dataset.keyCode = key.code;
|
||||||
}
|
}
|
||||||
@ -127,7 +125,7 @@ export class MkbRemapper {
|
|||||||
const keySlot = parseInt($elm.dataset.keySlot!);
|
const keySlot = parseInt($elm.dataset.keySlot!);
|
||||||
|
|
||||||
// Remove key from preset
|
// Remove key from preset
|
||||||
this.STATE.editingPresetData!.mapping[buttonIndex][keySlot] = null;
|
this.states.editingPresetData!.mapping[buttonIndex][keySlot] = null;
|
||||||
$elm.textContent = '';
|
$elm.textContent = '';
|
||||||
delete $elm.dataset.keyCode;
|
delete $elm.dataset.keyCode;
|
||||||
}
|
}
|
||||||
@ -161,7 +159,7 @@ export class MkbRemapper {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private onBindingKey = (e: MouseEvent) => {
|
private onBindingKey = (e: MouseEvent) => {
|
||||||
if (!this.STATE.isEditing || e.button !== 0) {
|
if (!this.states.isEditing || e.button !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +176,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
private onContextMenu = (e: Event) => {
|
private onContextMenu = (e: Event) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!this.STATE.isEditing) {
|
if (!this.states.isEditing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,15 +184,24 @@ export class MkbRemapper {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private getPreset = (presetId: number) => {
|
private getPreset = (presetId: number) => {
|
||||||
return this.STATE.presets[presetId];
|
return this.states.presets[presetId];
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCurrentPreset = () => {
|
private getCurrentPreset = () => {
|
||||||
return this.getPreset(this.STATE.currentPresetId);
|
let preset = this.getPreset(this.states.currentPresetId);
|
||||||
|
if (!preset) {
|
||||||
|
// Get the first preset in the list
|
||||||
|
const firstPresetId = parseInt(Object.keys(this.states.presets)[0]);
|
||||||
|
preset = this.states.presets[firstPresetId];
|
||||||
|
this.states.currentPresetId = firstPresetId;
|
||||||
|
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, firstPresetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
private switchPreset = (presetId: number) => {
|
private switchPreset = (presetId: number) => {
|
||||||
this.STATE.currentPresetId = presetId;
|
this.states.currentPresetId = presetId;
|
||||||
const presetData = this.getCurrentPreset().data;
|
const presetData = this.getCurrentPreset().data;
|
||||||
|
|
||||||
for (const $elm of this.allKeyElements) {
|
for (const $elm of this.allKeyElements) {
|
||||||
@ -223,26 +230,25 @@ export class MkbRemapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update state of Activate button
|
// Update state of Activate button
|
||||||
const activated = getPref(PrefKey.MKB_DEFAULT_PRESET_ID) === this.STATE.currentPresetId;
|
const activated = getPref(PrefKey.MKB_DEFAULT_PRESET_ID) === this.states.currentPresetId;
|
||||||
this.$activateButton.disabled = activated;
|
this.$activateButton.disabled = activated;
|
||||||
this.$activateButton.querySelector('span')!.textContent = activated ? t('activated') : t('activate');
|
this.$activateButton.querySelector('span')!.textContent = activated ? t('activated') : t('activate');
|
||||||
}
|
}
|
||||||
|
|
||||||
private refresh() {
|
private async refresh() {
|
||||||
// Clear presets select
|
// Clear presets select
|
||||||
while (this.$presetsSelect.firstChild) {
|
removeChildElements(this.$presetsSelect);
|
||||||
this.$presetsSelect.removeChild(this.$presetsSelect.firstChild);
|
|
||||||
}
|
|
||||||
|
|
||||||
MkbPresetsDb.getInstance().getPresets().then(presets => {
|
const presets = await MkbPresetsDb.getInstance().getPresets();
|
||||||
this.STATE.presets = presets;
|
|
||||||
const $fragment = document.createDocumentFragment();
|
this.states.presets = presets;
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
|
||||||
let defaultPresetId;
|
let defaultPresetId;
|
||||||
if (this.STATE.currentPresetId === 0) {
|
if (this.states.currentPresetId === 0) {
|
||||||
this.STATE.currentPresetId = parseInt(Object.keys(presets)[0]);
|
this.states.currentPresetId = parseInt(Object.keys(presets)[0]);
|
||||||
|
|
||||||
defaultPresetId = this.STATE.currentPresetId;
|
defaultPresetId = this.states.currentPresetId;
|
||||||
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, defaultPresetId);
|
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, defaultPresetId);
|
||||||
EmulatedMkbHandler.getInstance().refreshPresetData();
|
EmulatedMkbHandler.getInstance().refreshPresetData();
|
||||||
} else {
|
} else {
|
||||||
@ -257,30 +263,29 @@ export class MkbRemapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const $options = CE<HTMLOptionElement>('option', {value: id}, name);
|
const $options = CE<HTMLOptionElement>('option', {value: id}, name);
|
||||||
$options.selected = parseInt(id) === this.STATE.currentPresetId;
|
$options.selected = parseInt(id) === this.states.currentPresetId;
|
||||||
|
|
||||||
$fragment.appendChild($options);
|
fragment.appendChild($options);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$presetsSelect.appendChild($fragment);
|
this.$presetsSelect.appendChild(fragment);
|
||||||
|
|
||||||
// Update state of Activate button
|
// Update state of Activate button
|
||||||
const activated = defaultPresetId === this.STATE.currentPresetId;
|
const activated = defaultPresetId === this.states.currentPresetId;
|
||||||
this.$activateButton.disabled = activated;
|
this.$activateButton.disabled = activated;
|
||||||
this.$activateButton.querySelector('span')!.textContent = activated ? t('activated') : t('activate');
|
this.$activateButton.querySelector('span')!.textContent = activated ? t('activated') : t('activate');
|
||||||
|
|
||||||
!this.STATE.isEditing && this.switchPreset(this.STATE.currentPresetId);
|
!this.states.isEditing && this.switchPreset(this.states.currentPresetId);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private toggleEditing = (force?: boolean) => {
|
private toggleEditing = (force?: boolean) => {
|
||||||
this.STATE.isEditing = typeof force !== 'undefined' ? force : !this.STATE.isEditing;
|
this.states.isEditing = typeof force !== 'undefined' ? force : !this.states.isEditing;
|
||||||
this.$wrapper.classList.toggle('bx-editing', this.STATE.isEditing);
|
this.$wrapper.classList.toggle('bx-editing', this.states.isEditing);
|
||||||
|
|
||||||
if (this.STATE.isEditing) {
|
if (this.states.isEditing) {
|
||||||
this.STATE.editingPresetData = deepClone(this.getCurrentPreset().data);
|
this.states.editingPresetData = deepClone(this.getCurrentPreset().data);
|
||||||
} else {
|
} else {
|
||||||
this.STATE.editingPresetData = null;
|
this.states.editingPresetData = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -290,7 +295,7 @@ export class MkbRemapper {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let disable = !this.STATE.isEditing;
|
let disable = !this.states.isEditing;
|
||||||
|
|
||||||
if ($elm.parentElement!.classList.contains('bx-mkb-preset-tools')) {
|
if ($elm.parentElement!.classList.contains('bx-mkb-preset-tools')) {
|
||||||
disable = !disable;
|
disable = !disable;
|
||||||
@ -328,7 +333,7 @@ export class MkbRemapper {
|
|||||||
title: t('rename'),
|
title: t('rename'),
|
||||||
icon: BxIcon.CURSOR_TEXT,
|
icon: BxIcon.CURSOR_TEXT,
|
||||||
tabIndex: -1,
|
tabIndex: -1,
|
||||||
onClick: e => {
|
onClick: async () => {
|
||||||
const preset = this.getCurrentPreset();
|
const preset = this.getCurrentPreset();
|
||||||
|
|
||||||
let newName = promptNewName(preset.name);
|
let newName = promptNewName(preset.name);
|
||||||
@ -338,7 +343,9 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
// Update preset with new name
|
// Update preset with new name
|
||||||
preset.name = newName;
|
preset.name = newName;
|
||||||
MkbPresetsDb.getInstance().updatePreset(preset).then(id => this.refresh());
|
|
||||||
|
await MkbPresetsDb.getInstance().updatePreset(preset);
|
||||||
|
await this.refresh();
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -355,7 +362,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
// Create new preset selected name
|
// Create new preset selected name
|
||||||
MkbPresetsDb.getInstance().newPreset(newName, MkbPreset.DEFAULT_PRESET).then(id => {
|
MkbPresetsDb.getInstance().newPreset(newName, MkbPreset.DEFAULT_PRESET).then(id => {
|
||||||
this.STATE.currentPresetId = id;
|
this.states.currentPresetId = id;
|
||||||
this.refresh();
|
this.refresh();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -376,7 +383,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
// Create new preset selected name
|
// Create new preset selected name
|
||||||
MkbPresetsDb.getInstance().newPreset(newName, preset.data).then(id => {
|
MkbPresetsDb.getInstance().newPreset(newName, preset.data).then(id => {
|
||||||
this.STATE.currentPresetId = id;
|
this.states.currentPresetId = id;
|
||||||
this.refresh();
|
this.refresh();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -393,8 +400,8 @@ export class MkbRemapper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MkbPresetsDb.getInstance().deletePreset(this.STATE.currentPresetId).then(id => {
|
MkbPresetsDb.getInstance().deletePreset(this.states.currentPresetId).then(id => {
|
||||||
this.STATE.currentPresetId = 0;
|
this.states.currentPresetId = 0;
|
||||||
this.refresh();
|
this.refresh();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -448,7 +455,7 @@ export class MkbRemapper {
|
|||||||
|
|
||||||
let $elm;
|
let $elm;
|
||||||
const onChange = (e: Event, value: any) => {
|
const onChange = (e: Event, value: any) => {
|
||||||
(this.STATE.editingPresetData!.mouse as any)[key] = value;
|
(this.states.editingPresetData!.mouse as any)[key] = value;
|
||||||
};
|
};
|
||||||
const $row = CE('label', {
|
const $row = CE('label', {
|
||||||
class: 'bx-settings-row',
|
class: 'bx-settings-row',
|
||||||
@ -481,7 +488,7 @@ export class MkbRemapper {
|
|||||||
style: ButtonStyle.PRIMARY,
|
style: ButtonStyle.PRIMARY,
|
||||||
tabIndex: -1,
|
tabIndex: -1,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, this.STATE.currentPresetId);
|
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, this.states.currentPresetId);
|
||||||
EmulatedMkbHandler.getInstance().refreshPresetData();
|
EmulatedMkbHandler.getInstance().refreshPresetData();
|
||||||
|
|
||||||
this.refresh();
|
this.refresh();
|
||||||
@ -497,7 +504,7 @@ export class MkbRemapper {
|
|||||||
tabIndex: -1,
|
tabIndex: -1,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
// Restore preset
|
// Restore preset
|
||||||
this.switchPreset(this.STATE.currentPresetId);
|
this.switchPreset(this.states.currentPresetId);
|
||||||
this.toggleEditing(false);
|
this.toggleEditing(false);
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@ -509,7 +516,7 @@ export class MkbRemapper {
|
|||||||
tabIndex: -1,
|
tabIndex: -1,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
const updatedPreset = deepClone(this.getCurrentPreset());
|
const updatedPreset = deepClone(this.getCurrentPreset());
|
||||||
updatedPreset.data = this.STATE.editingPresetData as MkbPresetData;
|
updatedPreset.data = this.states.editingPresetData as MkbPresetData;
|
||||||
|
|
||||||
MkbPresetsDb.getInstance().updatePreset(updatedPreset).then(id => {
|
MkbPresetsDb.getInstance().updatePreset(updatedPreset).then(id => {
|
||||||
// If this is the default preset => refresh preset data
|
// If this is the default preset => refresh preset data
|
||||||
|
@ -32,65 +32,65 @@ export class MkbPresetsDb extends LocalDb {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private presetsTable() {
|
private async presetsTable() {
|
||||||
return this.open()
|
await this.open();
|
||||||
.then(() => this.table(this.TABLE_PRESETS, 'readwrite'))
|
return await this.table(this.TABLE_PRESETS, 'readwrite');
|
||||||
}
|
}
|
||||||
|
|
||||||
newPreset(name: string, data: any) {
|
async newPreset(name: string, data: any) {
|
||||||
return this.presetsTable()
|
const table = await this.presetsTable();
|
||||||
.then(table => this.add(table, {name, data}))
|
const [, id] = await this.add(table, { name, data });
|
||||||
.then(([table, id]) => new Promise<number>(resolve => resolve(id)));
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePreset(preset: MkbStoredPreset) {
|
async updatePreset(preset: MkbStoredPreset) {
|
||||||
return this.presetsTable()
|
const table = await this.presetsTable();
|
||||||
.then(table => this.put(table, preset))
|
const [, id] = await this.put(table, preset);
|
||||||
.then(([table, id]) => new Promise(resolve => resolve(id)));
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
deletePreset(id: number) {
|
async deletePreset(id: number) {
|
||||||
return this.presetsTable()
|
const table = await this.presetsTable();
|
||||||
.then(table => this.delete(table, id))
|
await this.delete(table, id);
|
||||||
.then(([table, id]) => new Promise(resolve => resolve(id)));
|
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPreset(id: number): Promise<MkbStoredPreset> {
|
async getPreset(id: number): Promise<MkbStoredPreset> {
|
||||||
return this.presetsTable()
|
const table = await this.presetsTable();
|
||||||
.then(table => this.get(table, id))
|
const [, preset] = await this.get(table, id);
|
||||||
.then(([table, preset]) => new Promise(resolve => resolve(preset)));
|
|
||||||
|
return preset;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPresets(): Promise<MkbStoredPresets> {
|
async getPresets(): Promise<MkbStoredPresets> {
|
||||||
return this.presetsTable()
|
const table = await this.presetsTable();
|
||||||
.then(table => this.count(table))
|
const [, count] = await this.count(table);
|
||||||
.then(([table, count]) => {
|
|
||||||
|
// Return stored presets
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
return new Promise(resolve => {
|
const [, items] = await this.getAll(table);
|
||||||
this.getAll(table)
|
|
||||||
.then(([table, items]) => {
|
|
||||||
const presets: MkbStoredPresets = {};
|
const presets: MkbStoredPresets = {};
|
||||||
items.forEach((item: MkbStoredPreset) => (presets[item.id!] = item));
|
items.forEach((item: MkbStoredPreset) => (presets[item.id!] = item));
|
||||||
resolve(presets);
|
|
||||||
});
|
return presets;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create "Default" preset when the table is empty
|
// Create "Default" preset when the table is empty
|
||||||
const preset: MkbStoredPreset = {
|
const preset: MkbStoredPreset = {
|
||||||
name: t('default'),
|
name: t('default'),
|
||||||
data: MkbPreset.DEFAULT_PRESET,
|
data: MkbPreset.DEFAULT_PRESET,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const [, id] = await this.add(table, preset);
|
||||||
|
|
||||||
return new Promise<MkbStoredPresets>(resolve => {
|
|
||||||
this.add(table, preset)
|
|
||||||
.then(([table, id]) => {
|
|
||||||
preset.id = id;
|
preset.id = id;
|
||||||
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, id);
|
setPref(PrefKey.MKB_DEFAULT_PRESET_ID, id);
|
||||||
|
|
||||||
resolve({[id]: preset});
|
return {
|
||||||
});
|
[id]: preset,
|
||||||
});
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user