mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 12:49:25 +08:00
feat: 自定义状态栏编辑工具框架
This commit is contained in:
parent
49d8050e03
commit
60d708e5e3
5
.gitignore
vendored
5
.gitignore
vendored
@ -41,4 +41,7 @@ dam1.png
|
|||||||
dam2.png
|
dam2.png
|
||||||
dam3.png
|
dam3.png
|
||||||
dam4.png
|
dam4.png
|
||||||
meeting.md
|
meeting.md
|
||||||
|
|
||||||
|
special.csv
|
||||||
|
script/special.ts
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="colomn">
|
<div class="colomn">
|
||||||
<div class="tools">
|
<div class="tools">
|
||||||
<span class="button-text" @click="emits('close')"
|
<span class="button-text" @click="emits('close')"
|
||||||
><left-outlined /> 返回游戏</span
|
><left-outlined /> 返回</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="column-main" :id="`column-${id}`">
|
<div class="column-main" :id="`column-${id}`">
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
import { EmitableEvent, EventEmitter } from '@/core/common/eventEmitter';
|
import { EmitableEvent, EventEmitter } from '@/core/common/eventEmitter';
|
||||||
import { KeyCode } from '@/plugin/keyCodes';
|
import { KeyCode } from '@/plugin/keyCodes';
|
||||||
import { flipBinary, has } from '@/plugin/utils';
|
import { flipBinary, has } from '@/plugin/utils';
|
||||||
import { FunctionalComponent, nextTick, reactive } from 'vue';
|
import {
|
||||||
|
FunctionalComponent,
|
||||||
|
markRaw,
|
||||||
|
nextTick,
|
||||||
|
reactive,
|
||||||
|
shallowReactive
|
||||||
|
} from 'vue';
|
||||||
import { createToolbarComponents } from '../init/toolbar';
|
import { createToolbarComponents } from '../init/toolbar';
|
||||||
import { gameKey } from '../init/hotkey';
|
import { gameKey } from '../init/hotkey';
|
||||||
import { unwarpBinary } from './hotkey';
|
import { unwarpBinary } from './hotkey';
|
||||||
@ -12,7 +18,7 @@ interface CustomToolbarEvent extends EmitableEvent {
|
|||||||
add: (item: ValueOf<ToolbarItemMap>) => void;
|
add: (item: ValueOf<ToolbarItemMap>) => void;
|
||||||
delete: (item: ValueOf<ToolbarItemMap>) => void;
|
delete: (item: ValueOf<ToolbarItemMap>) => void;
|
||||||
set: (id: string, data: Partial<SettableItemData>) => void;
|
set: (id: string, data: Partial<SettableItemData>) => void;
|
||||||
emit: (id: string) => void;
|
emit: (id: string, item: ValueOf<ToolbarItemMap>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ToolbarItemBase<T extends ToolbarItemType> {
|
interface ToolbarItemBase<T extends ToolbarItemType> {
|
||||||
@ -70,7 +76,7 @@ const comMap: {
|
|||||||
|
|
||||||
export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
|
export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
|
||||||
static num: number = 0;
|
static num: number = 0;
|
||||||
static list: CustomToolbar[] = [];
|
static list: CustomToolbar[] = shallowReactive([]);
|
||||||
|
|
||||||
items: ValueOf<ToolbarItemMap>[] = reactive([]);
|
items: ValueOf<ToolbarItemMap>[] = reactive([]);
|
||||||
num: number = CustomToolbar.num++;
|
num: number = CustomToolbar.num++;
|
||||||
@ -97,7 +103,7 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
|
|||||||
add<K extends ToolbarItemType>(item: Omit<ToolbarItemMap[K], 'com'>) {
|
add<K extends ToolbarItemType>(item: Omit<ToolbarItemMap[K], 'com'>) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const data: ToolbarItemMap[K] = {
|
const data: ToolbarItemMap[K] = {
|
||||||
com: comMap[item.type],
|
com: markRaw(comMap[item.type]),
|
||||||
...item
|
...item
|
||||||
} as ToolbarItemMap[K];
|
} as ToolbarItemMap[K];
|
||||||
this.items.push(data);
|
this.items.push(data);
|
||||||
@ -141,7 +147,7 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
|
|||||||
emitTool(id: string) {
|
emitTool(id: string) {
|
||||||
const item = this.items.find(v => v.id === id);
|
const item = this.items.find(v => v.id === id);
|
||||||
if (!item) return this;
|
if (!item) return this;
|
||||||
this.emit(id);
|
this.emit('emit', id, item);
|
||||||
if (item.type === 'hotkey') {
|
if (item.type === 'hotkey') {
|
||||||
// 按键
|
// 按键
|
||||||
const assist = item.assist | this.assistKey;
|
const assist = item.assist | this.assistKey;
|
||||||
|
@ -8,7 +8,7 @@ interface Components {
|
|||||||
BooleanSetting: SettingComponent;
|
BooleanSetting: SettingComponent;
|
||||||
NumberSetting: SettingComponent;
|
NumberSetting: SettingComponent;
|
||||||
HotkeySetting: SettingComponent;
|
HotkeySetting: SettingComponent;
|
||||||
ToolbarSetting: SettingComponent;
|
ToolbarEditor: SettingComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSettingComponents() {
|
export function createSettingComponents() {
|
||||||
@ -17,7 +17,7 @@ export function createSettingComponents() {
|
|||||||
BooleanSetting,
|
BooleanSetting,
|
||||||
NumberSetting,
|
NumberSetting,
|
||||||
HotkeySetting,
|
HotkeySetting,
|
||||||
ToolbarSetting
|
ToolbarEditor
|
||||||
};
|
};
|
||||||
return com;
|
return com;
|
||||||
}
|
}
|
||||||
@ -104,15 +104,14 @@ function HotkeySetting(props: SettingComponentProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ToolbarSetting(props: SettingComponentProps) {
|
function ToolbarEditor(props: SettingComponentProps) {
|
||||||
// todo: toolSetting.vue
|
|
||||||
return (
|
return (
|
||||||
<div style="display: flex; justify-content: center">
|
<div style="display: flex; justify-content: center">
|
||||||
<Button
|
<Button
|
||||||
style="font-size: 75%"
|
style="font-size: 75%"
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
onClick={() => showSpecialSetting('toolSetting')}
|
onClick={() => showSpecialSetting('toolEditor')}
|
||||||
>
|
>
|
||||||
自定义工具栏
|
自定义工具栏
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -16,7 +16,8 @@ mainUi.register(
|
|||||||
new GameUi('shop', UI.Shop),
|
new GameUi('shop', UI.Shop),
|
||||||
new GameUi('achievement', UI.Achievement),
|
new GameUi('achievement', UI.Achievement),
|
||||||
new GameUi('bgm', UI.BgmList),
|
new GameUi('bgm', UI.BgmList),
|
||||||
new GameUi('hotkey', UI.Hotkey)
|
new GameUi('hotkey', UI.Hotkey),
|
||||||
|
new GameUi('toolEditor', UI.ToolEditor)
|
||||||
// todo: 把游戏主 div 加入到 mainUi 里面
|
// todo: 把游戏主 div 加入到 mainUi 里面
|
||||||
);
|
);
|
||||||
mainUi.showAll();
|
mainUi.showAll();
|
||||||
|
@ -391,7 +391,7 @@ mainSetting
|
|||||||
.register('fixed', '定点查看', true, COM.BooleanSetting)
|
.register('fixed', '定点查看', true, COM.BooleanSetting)
|
||||||
.register('hotkey', '快捷键', false, COM.HotkeySetting)
|
.register('hotkey', '快捷键', false, COM.HotkeySetting)
|
||||||
.setDisplayFunc('hotkey', () => '')
|
.setDisplayFunc('hotkey', () => '')
|
||||||
.register('toolbar', '自定义工具栏', false, COM.BooleanSetting)
|
.register('toolbar', '自定义工具栏', false, COM.ToolbarEditor)
|
||||||
.setDisplayFunc('toolbar', () => '')
|
.setDisplayFunc('toolbar', () => '')
|
||||||
)
|
)
|
||||||
.register(
|
.register(
|
||||||
|
@ -21,3 +21,4 @@ export { default as Study } from './study.vue';
|
|||||||
export { default as Toolbox } from './toolbox.vue';
|
export { default as Toolbox } from './toolbox.vue';
|
||||||
export { default as Hotkey } from './hotkey.vue';
|
export { default as Hotkey } from './hotkey.vue';
|
||||||
export { default as Toolbar } from './toolbar.vue';
|
export { default as Toolbar } from './toolbar.vue';
|
||||||
|
export { default as ToolEditor } from './toolEditor.vue';
|
||||||
|
140
src/ui/toolEditor.vue
Normal file
140
src/ui/toolEditor.vue
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<template>
|
||||||
|
<Column :left="30" @close="exit">
|
||||||
|
<template #left>
|
||||||
|
<div id="tool-list">
|
||||||
|
<div
|
||||||
|
v-for="(item, i) of list"
|
||||||
|
class="tool-list-item selectable"
|
||||||
|
:selected="i === selected"
|
||||||
|
@click="selected = i"
|
||||||
|
>
|
||||||
|
<span>{{ item.id }}</span>
|
||||||
|
<a-button
|
||||||
|
type="danger"
|
||||||
|
class="tool-list-delete"
|
||||||
|
@click.stop="deleteTool"
|
||||||
|
>删除</a-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div id="tool-list-add">
|
||||||
|
<div id="tool-add-div" @click="addTool">
|
||||||
|
<PlusOutlined></PlusOutlined>
|
||||||
|
<span>新增工具栏</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<div id="tool-info">
|
||||||
|
<div id="tool-detail"></div>
|
||||||
|
<a-divider dashed></a-divider>
|
||||||
|
<div id="tool-preview">
|
||||||
|
<div id="tool-preview-container">
|
||||||
|
<div
|
||||||
|
class="tool-preview-item"
|
||||||
|
v-for="item of bar.items"
|
||||||
|
>
|
||||||
|
<component
|
||||||
|
:is="(item.com as any)"
|
||||||
|
:item="item"
|
||||||
|
:bar="bar"
|
||||||
|
></component>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</Column>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { CustomToolbar } from '@/core/main/custom/toolbar';
|
||||||
|
import { GameUi } from '@/core/main/custom/ui';
|
||||||
|
import Column from '../components/colomn.vue';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { PlusOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { mainUi } from '@/core/main/init/ui';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
ui: GameUi;
|
||||||
|
num: number;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const list = CustomToolbar.list;
|
||||||
|
|
||||||
|
const selected = ref(0);
|
||||||
|
const bar = computed(() => list[selected.value]);
|
||||||
|
|
||||||
|
function exit() {
|
||||||
|
mainUi.close(props.num);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteTool() {}
|
||||||
|
|
||||||
|
function addTool() {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.tool-list-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool-list-add {
|
||||||
|
margin-top: 5%;
|
||||||
|
padding: 1% 3% 1% 3%;
|
||||||
|
|
||||||
|
#tool-add-div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 1% 4%;
|
||||||
|
transition: background-color linear 0.1s;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool-add-div:hover {
|
||||||
|
background-color: rgba(39, 251, 209, 0.316);
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool-add-div:active {
|
||||||
|
background-color: rgba(39, 251, 209, 0.202);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-list-delete {
|
||||||
|
font-size: 80%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool-info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tool-preview {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
#tool-preview-container {
|
||||||
|
border: 2px solid #ddd9;
|
||||||
|
background-color: #0009;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-preview-item {
|
||||||
|
::v-deep(*) {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user