mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 12:49:25 +08:00
feat: 自定义按键
This commit is contained in:
parent
1e58dbe411
commit
770e38202c
@ -59,22 +59,22 @@ function resize() {
|
||||
if (has(props.right)) right.style.flexBasis = `${props.right}%`;
|
||||
}
|
||||
|
||||
function key(e: KeyboardEvent) {
|
||||
const c = keycode(e.keyCode);
|
||||
if (c === KeyCode.Escape || c === KeyCode.KeyX) emits('close');
|
||||
}
|
||||
// function key(e: KeyboardEvent) {
|
||||
// const c = keycode(e.keyCode);
|
||||
// if (c === KeyCode.Escape || c === KeyCode.KeyX) emits('close');
|
||||
// }
|
||||
|
||||
onMounted(async () => {
|
||||
resize();
|
||||
|
||||
await sleep(50);
|
||||
// if (mota.plugin.ui.transition.value) await sleep(600);
|
||||
document.addEventListener('keyup', key);
|
||||
// document.addEventListener('keyup', key);
|
||||
});
|
||||
onUpdated(resize);
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keyup', key);
|
||||
// document.removeEventListener('keyup', key);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -15,7 +15,10 @@ gameKey
|
||||
.register({
|
||||
id: 'book',
|
||||
name: '怪物手册',
|
||||
defaults: KeyCode.KeyX
|
||||
defaults: KeyCode.KeyX,
|
||||
ctrl: true,
|
||||
shift: true,
|
||||
alt: true
|
||||
})
|
||||
.register({
|
||||
id: 'save',
|
||||
|
@ -1,6 +1,7 @@
|
||||
import type { SettingComponent, SettingComponentProps } from '../setting';
|
||||
import { Button, InputNumber } from 'ant-design-vue';
|
||||
import { mainUi } from './ui';
|
||||
import { gameKey } from './hotkey';
|
||||
|
||||
interface Components {
|
||||
DefaultSetting: SettingComponent;
|
||||
@ -70,13 +71,13 @@ function NumberSetting(props: SettingComponentProps) {
|
||||
);
|
||||
}
|
||||
|
||||
function showSpecialSetting(id: string) {
|
||||
function showSpecialSetting(id: string, vBind?: any) {
|
||||
const ui = mainUi.get(id);
|
||||
mainUi.showEnd();
|
||||
ui.once('close', () => {
|
||||
mainUi.showAll();
|
||||
});
|
||||
mainUi.open(id);
|
||||
mainUi.open(id, vBind);
|
||||
}
|
||||
|
||||
function HotkeySetting(props: SettingComponentProps) {
|
||||
@ -86,7 +87,11 @@ function HotkeySetting(props: SettingComponentProps) {
|
||||
<Button
|
||||
type="primary"
|
||||
size="large"
|
||||
onClick={() => showSpecialSetting('hotkey')}
|
||||
onClick={() =>
|
||||
showSpecialSetting('hotkey', {
|
||||
hotkey: gameKey
|
||||
})
|
||||
}
|
||||
>
|
||||
快捷键设置
|
||||
</Button>
|
||||
|
@ -15,7 +15,8 @@ mainUi.register(
|
||||
new GameUi('fixedDetail', UI.FixedDetail),
|
||||
new GameUi('shop', UI.Shop),
|
||||
new GameUi('achievement', UI.Achievement),
|
||||
new GameUi('bgm', UI.BgmList)
|
||||
new GameUi('bgm', UI.BgmList),
|
||||
new GameUi('hotkey', UI.Hotkey)
|
||||
// todo: 把游戏主 div 加入到 mainUi 里面
|
||||
);
|
||||
mainUi.showAll();
|
||||
|
@ -389,7 +389,7 @@ mainSetting
|
||||
new MotaSetting()
|
||||
.register('autoSkill', '自动切换技能', true, COM.BooleanSetting)
|
||||
.register('fixed', '定点查看', true, COM.BooleanSetting)
|
||||
.register('hotkey', '快捷键', false, COM.BooleanSetting)
|
||||
.register('hotkey', '快捷键', false, COM.HotkeySetting)
|
||||
.setDisplayFunc('hotkey', () => '')
|
||||
.register('toolbar', '自定义工具栏', false, COM.BooleanSetting)
|
||||
.setDisplayFunc('toolbar', () => '')
|
||||
|
229
src/ui/hotkey.vue
Normal file
229
src/ui/hotkey.vue
Normal file
@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<Column @close="close" :left="30">
|
||||
<template #left>
|
||||
<div id="hotkey-group">
|
||||
<span
|
||||
class="hotkey-group-one selectable"
|
||||
v-for="(name, group) of groupName"
|
||||
:selected="selectedGroup === group"
|
||||
@click="selectedGroup = group"
|
||||
>
|
||||
{{ name }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #right>
|
||||
<div id="hotkey-data">
|
||||
<div class="hotkey-one" v-for="(data, id) of show">
|
||||
<span class="hotkey-one-name"> {{ data.name }} </span>
|
||||
<div class="hotkey-one-set">
|
||||
<span
|
||||
v-for="key of data.keys"
|
||||
class="hotkey-one-set-item"
|
||||
:selected="
|
||||
data.id === selectedKey.id &&
|
||||
key.index === selectedKey.index
|
||||
"
|
||||
@click="select(data.id, key.index)"
|
||||
>
|
||||
{{ getKeyShow(key.key, key.assist) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Column>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Hotkey } from '@/core/main/custom/hotkey';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
import Column from '@/components/colomn.vue';
|
||||
import { mainUi } from '@/core/main/init/ui';
|
||||
import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';
|
||||
import { KeyCode, KeyCodeUtils } from '@/plugin/keyCodes';
|
||||
import { generateBinary, keycode } from '@/plugin/utils';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { gameKey } from '@/core/main/init/hotkey';
|
||||
|
||||
interface HotkeyKeys {
|
||||
index: number;
|
||||
key: KeyCode;
|
||||
/** 从低到高依次为 `ctrl` `shift` `alt` */
|
||||
assist: number;
|
||||
}
|
||||
|
||||
interface HotkeySetting {
|
||||
id: string;
|
||||
name: string;
|
||||
keys: HotkeyKeys[];
|
||||
}
|
||||
|
||||
interface SelectedKey {
|
||||
id: string;
|
||||
index: number;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
num: number;
|
||||
ui: GameUi;
|
||||
hotkey: Hotkey;
|
||||
}>();
|
||||
|
||||
const hotkey = props.hotkey;
|
||||
|
||||
function close() {
|
||||
mainUi.close(props.num);
|
||||
}
|
||||
|
||||
const selectedGroup = ref('ui');
|
||||
const keyData = generateData();
|
||||
const show = computed(() => {
|
||||
return keyData[selectedGroup.value];
|
||||
});
|
||||
const groupName = cloneDeep(hotkey.groupName);
|
||||
delete groupName.none;
|
||||
|
||||
const selectedKey: SelectedKey = reactive({
|
||||
id: 'none',
|
||||
index: -1
|
||||
});
|
||||
|
||||
function generateData() {
|
||||
const res: Record<string, Record<string, HotkeySetting>> = {};
|
||||
|
||||
for (const [group, data] of Object.entries(hotkey.groups)) {
|
||||
if (group === 'none') continue;
|
||||
res[group] = {};
|
||||
const d = res[group];
|
||||
data.forEach(v => {
|
||||
const split = v.split('_');
|
||||
const isMulti = /^\d+$/.test(split.at(-1)!);
|
||||
const id = isMulti ? split.slice(0, -1).join('_') : v;
|
||||
const index = isMulti ? parseInt(split.at(-1)!) : -1;
|
||||
|
||||
const key = hotkey.data[v];
|
||||
d[id] ??= {
|
||||
id,
|
||||
name: isMulti
|
||||
? key.name.split('_').slice(0, -1).join('_')
|
||||
: key.name,
|
||||
keys: reactive([])
|
||||
};
|
||||
d[id].keys.push({
|
||||
index,
|
||||
key: key.key,
|
||||
assist: generateBinary([key.ctrl, key.shift, key.alt])
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function unwarpAssist(assist: number) {
|
||||
let res = '';
|
||||
if (assist & (1 << 0)) {
|
||||
res += 'Ctrl + ';
|
||||
}
|
||||
if (assist & (1 << 1)) {
|
||||
res += 'Shift + ';
|
||||
}
|
||||
if (assist & (1 << 2)) {
|
||||
res += 'Alt + ';
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function getKeyShow(key: KeyCode, assist: number) {
|
||||
return unwarpAssist(assist) + KeyCodeUtils.toString(key);
|
||||
}
|
||||
|
||||
function select(id: string, index: number) {
|
||||
selectedKey.id = id;
|
||||
selectedKey.index = index;
|
||||
}
|
||||
|
||||
function keyup(e: KeyboardEvent) {
|
||||
if (selectedKey.id === 'none') return;
|
||||
const code = keycode(e.keyCode);
|
||||
if (
|
||||
code === KeyCode.Ctrl ||
|
||||
code === KeyCode.Shift ||
|
||||
code === KeyCode.Alt
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const assist = generateBinary([e.ctrlKey, e.shiftKey, e.altKey]);
|
||||
const id =
|
||||
selectedKey.index === -1
|
||||
? selectedKey.id
|
||||
: `${selectedKey.id}_${selectedKey.index}`;
|
||||
|
||||
hotkey.set(id, code, assist);
|
||||
const key = keyData[selectedGroup.value][selectedKey.id].keys.find(
|
||||
v => v.index === selectedKey.index
|
||||
);
|
||||
if (key) {
|
||||
key.key = code;
|
||||
key.assist = assist;
|
||||
}
|
||||
|
||||
selectedKey.id = 'none';
|
||||
selectedKey.index = -1;
|
||||
}
|
||||
|
||||
// ban other keys
|
||||
gameKey.disable();
|
||||
console.log(gameKey.enabled);
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('keyup', keyup);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
gameKey.enable();
|
||||
document.removeEventListener('keyup', keyup);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#hotkey-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.hotkey-group-one {
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.hotkey-one {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin: 2% 3%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.hotkey-one-set {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
text-overflow: clip;
|
||||
align-items: end;
|
||||
text-align: end;
|
||||
|
||||
.hotkey-one-set-item {
|
||||
background-color: #4446;
|
||||
padding: 0 5%;
|
||||
margin: 1% 0;
|
||||
width: 100%;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.hotkey-one-set-item[selected='true'] {
|
||||
color: gold;
|
||||
border: 1px solid gold;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -19,3 +19,4 @@ export { default as StatusBar } from './statusBar.vue';
|
||||
export { default as Studied } from './studied.vue';
|
||||
export { default as Study } from './study.vue';
|
||||
export { default as Toolbox } from './toolbox.vue';
|
||||
export { default as Hotkey } from './hotkey.vue';
|
||||
|
@ -83,11 +83,14 @@ import Scroll from '../components/scroll.vue';
|
||||
import { isMobile } from '../plugin/use';
|
||||
import { sleep } from 'mutate-animate';
|
||||
import { KeyCode } from '../plugin/keyCodes';
|
||||
import { gameKey } from '@/core/main/init/hotkey';
|
||||
import { GameUi } from '@/core/main/custom/ui';
|
||||
|
||||
const props = defineProps<{
|
||||
info?: MotaSetting;
|
||||
text?: SettingText;
|
||||
num: number;
|
||||
ui: GameUi;
|
||||
}>();
|
||||
|
||||
const setting = props.info ?? mainSetting;
|
||||
@ -143,19 +146,13 @@ function exit() {
|
||||
mota.ui.main.close(props.num);
|
||||
}
|
||||
|
||||
function key(e: KeyboardEvent) {
|
||||
const c = keycode(e.keyCode);
|
||||
if (c === KeyCode.Escape || c === KeyCode.KeyX) exit();
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await sleep(50);
|
||||
// if (mota.plugin.ui.transition.value) await sleep(600);
|
||||
document.addEventListener('keyup', key);
|
||||
gameKey.use(props.ui.symbol);
|
||||
gameKey.realize('exit', () => {
|
||||
exit();
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('keyup', key);
|
||||
gameKey.dispose(props.ui.symbol);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user