feat: 自定义状态栏编辑工具框架

This commit is contained in:
unanmed 2023-12-29 23:10:09 +08:00
parent 49d8050e03
commit 60d708e5e3
8 changed files with 164 additions and 14 deletions

5
.gitignore vendored
View File

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

View File

@ -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}`">

View File

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

View File

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

View File

@ -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();

View File

@ -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(

View File

@ -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
View 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>&nbsp;&nbsp;
<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>