mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-11-04 07:02:58 +08:00 
			
		
		
		
	feat: 自定义状态栏的编辑
This commit is contained in:
		
							parent
							
								
									1e341fb63e
								
							
						
					
					
						commit
						ad2cb0b757
					
				
							
								
								
									
										1
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								components.d.ts
									
									
									
									
										vendored
									
									
								
							@ -9,6 +9,7 @@ declare module '@vue/runtime-core' {
 | 
				
			|||||||
  export interface GlobalComponents {
 | 
					  export interface GlobalComponents {
 | 
				
			||||||
    AButton: typeof import('ant-design-vue/es')['Button']
 | 
					    AButton: typeof import('ant-design-vue/es')['Button']
 | 
				
			||||||
    ADivider: typeof import('ant-design-vue/es')['Divider']
 | 
					    ADivider: typeof import('ant-design-vue/es')['Divider']
 | 
				
			||||||
 | 
					    AInput: typeof import('ant-design-vue/es')['Input']
 | 
				
			||||||
    AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
 | 
					    AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
 | 
				
			||||||
    AProgress: typeof import('ant-design-vue/es')['Progress']
 | 
					    AProgress: typeof import('ant-design-vue/es')['Progress']
 | 
				
			||||||
    ASelect: typeof import('ant-design-vue/es')['Select']
 | 
					    ASelect: typeof import('ant-design-vue/es')['Select']
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/App.vue
									
									
									
									
									
								
							@ -1,5 +1,5 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div id="ui-new">
 | 
					    <div id="ui">
 | 
				
			||||||
        <div id="ui-main">
 | 
					        <div id="ui-main">
 | 
				
			||||||
            <div id="ui-list">
 | 
					            <div id="ui-list">
 | 
				
			||||||
                <div class="ui-one" v-for="(ui, index) of mainUi.stack">
 | 
					                <div class="ui-one" v-for="(ui, index) of mainUi.stack">
 | 
				
			||||||
@ -41,14 +41,6 @@ function show(index: number) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<style lang="less" scoped>
 | 
					<style lang="less" scoped>
 | 
				
			||||||
#ui {
 | 
					#ui {
 | 
				
			||||||
    width: 90%;
 | 
					 | 
				
			||||||
    height: 90%;
 | 
					 | 
				
			||||||
    display: flex;
 | 
					 | 
				
			||||||
    justify-content: center;
 | 
					 | 
				
			||||||
    overflow: hidden;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ui-new {
 | 
					 | 
				
			||||||
    width: 0;
 | 
					    width: 0;
 | 
				
			||||||
    height: 0;
 | 
					    height: 0;
 | 
				
			||||||
    left: 0;
 | 
					    left: 0;
 | 
				
			||||||
@ -56,6 +48,7 @@ function show(index: number) {
 | 
				
			|||||||
    position: fixed;
 | 
					    position: fixed;
 | 
				
			||||||
    overflow: visible;
 | 
					    overflow: visible;
 | 
				
			||||||
    display: block;
 | 
					    display: block;
 | 
				
			||||||
 | 
					    font-family: 'normal';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ui-main {
 | 
					#ui-main {
 | 
				
			||||||
 | 
				
			|||||||
@ -93,8 +93,8 @@ export class Keyboard extends EventEmitter<VirtualKeyboardEvent> {
 | 
				
			|||||||
     * @param assist 辅助按键
 | 
					     * @param assist 辅助按键
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    withAssist(assist: number) {
 | 
					    withAssist(assist: number) {
 | 
				
			||||||
        this.assist = assist;
 | 
					 | 
				
			||||||
        const symbol = this.createScope();
 | 
					        const symbol = this.createScope();
 | 
				
			||||||
 | 
					        this.assist = assist;
 | 
				
			||||||
        return symbol;
 | 
					        return symbol;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
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 { deleteWith, flipBinary, has } from '@/plugin/utils';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    FunctionalComponent,
 | 
					    FunctionalComponent,
 | 
				
			||||||
    markRaw,
 | 
					    markRaw,
 | 
				
			||||||
@ -8,7 +8,10 @@ import {
 | 
				
			|||||||
    reactive,
 | 
					    reactive,
 | 
				
			||||||
    shallowReactive
 | 
					    shallowReactive
 | 
				
			||||||
} from 'vue';
 | 
					} from 'vue';
 | 
				
			||||||
import { createToolbarComponents } from '../init/toolbar';
 | 
					import {
 | 
				
			||||||
 | 
					    createToolbarComponents,
 | 
				
			||||||
 | 
					    createToolbarEditorComponents
 | 
				
			||||||
 | 
					} from '../init/toolbar';
 | 
				
			||||||
import { gameKey } from '../init/hotkey';
 | 
					import { gameKey } from '../init/hotkey';
 | 
				
			||||||
import { unwarpBinary } from './hotkey';
 | 
					import { unwarpBinary } from './hotkey';
 | 
				
			||||||
import { fixedUi } from '../init/ui';
 | 
					import { fixedUi } from '../init/ui';
 | 
				
			||||||
@ -24,7 +27,6 @@ interface CustomToolbarEvent extends EmitableEvent {
 | 
				
			|||||||
interface ToolbarItemBase<T extends ToolbarItemType> {
 | 
					interface ToolbarItemBase<T extends ToolbarItemType> {
 | 
				
			||||||
    type: T;
 | 
					    type: T;
 | 
				
			||||||
    id: string;
 | 
					    id: string;
 | 
				
			||||||
    com: CustomToolbarComponent<T>;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 快捷键
 | 
					// 快捷键
 | 
				
			||||||
@ -49,7 +51,7 @@ interface ToolbarItemMap {
 | 
				
			|||||||
    assistKey: AssistKeyToolbarItem;
 | 
					    assistKey: AssistKeyToolbarItem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ToolbarItemType = keyof ToolbarItemMap;
 | 
					export type ToolbarItemType = keyof ToolbarItemMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type SettableItemData<T extends ToolbarItemType = ToolbarItemType> =
 | 
					export type SettableItemData<T extends ToolbarItemType = ToolbarItemType> =
 | 
				
			||||||
    Omit<ToolbarItemMap[T], 'id' | 'type'>;
 | 
					    Omit<ToolbarItemMap[T], 'id' | 'type'>;
 | 
				
			||||||
@ -64,19 +66,27 @@ export type CustomToolbarComponent<
 | 
				
			|||||||
    T extends ToolbarItemType = ToolbarItemType
 | 
					    T extends ToolbarItemType = ToolbarItemType
 | 
				
			||||||
> = FunctionalComponent<CustomToolbarProps<T>>;
 | 
					> = FunctionalComponent<CustomToolbarProps<T>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const COM = createToolbarComponents();
 | 
					type ToolItemEmitFn<T extends ToolbarItemType> = (
 | 
				
			||||||
 | 
					    this: CustomToolbar,
 | 
				
			||||||
 | 
					    id: string,
 | 
				
			||||||
 | 
					    item: ToolbarItemMap[T]
 | 
				
			||||||
 | 
					) => boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const comMap: {
 | 
					interface RegisteredCustomToolInfo {
 | 
				
			||||||
    [P in ToolbarItemType]: CustomToolbarComponent<P>;
 | 
					    name: string;
 | 
				
			||||||
} = {
 | 
					    onEmit: ToolItemEmitFn<ToolbarItemType>;
 | 
				
			||||||
    hotkey: COM.KeyTool,
 | 
					    show: CustomToolbarComponent;
 | 
				
			||||||
    item: COM.ItemTool,
 | 
					    editor: CustomToolbarComponent;
 | 
				
			||||||
    assistKey: COM.AssistKeyTool
 | 
					    onCreate: (item: any) => ToolbarItemBase<ToolbarItemType>;
 | 
				
			||||||
};
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const COM = createToolbarComponents();
 | 
				
			||||||
 | 
					const EDITOR = createToolbarEditorComponents();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
 | 
					export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
 | 
				
			||||||
    static num: number = 0;
 | 
					    static num: number = 0;
 | 
				
			||||||
    static list: CustomToolbar[] = shallowReactive([]);
 | 
					    static list: CustomToolbar[] = shallowReactive([]);
 | 
				
			||||||
 | 
					    static info: Record<string, RegisteredCustomToolInfo> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    items: ValueOf<ToolbarItemMap>[] = reactive([]);
 | 
					    items: ValueOf<ToolbarItemMap>[] = reactive([]);
 | 
				
			||||||
    num: number = CustomToolbar.num++;
 | 
					    num: number = CustomToolbar.num++;
 | 
				
			||||||
@ -88,6 +98,7 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
 | 
				
			|||||||
    height: number = 70;
 | 
					    height: number = 70;
 | 
				
			||||||
    // ----- other
 | 
					    // ----- other
 | 
				
			||||||
    assistKey: number = 0;
 | 
					    assistKey: number = 0;
 | 
				
			||||||
 | 
					    showIds: number[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(id: string) {
 | 
					    constructor(id: string) {
 | 
				
			||||||
        super();
 | 
					        super();
 | 
				
			||||||
@ -100,14 +111,15 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
 | 
				
			|||||||
     * 添加一个自定义项
 | 
					     * 添加一个自定义项
 | 
				
			||||||
     * @param item 要添加的自定义工具栏项
 | 
					     * @param item 要添加的自定义工具栏项
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    add<K extends ToolbarItemType>(item: Omit<ToolbarItemMap[K], 'com'>) {
 | 
					    add<K extends ToolbarItemType>(item: ToolbarItemMap[K]) {
 | 
				
			||||||
        // @ts-ignore
 | 
					        const index = this.items.findIndex(v => v.id === item.id);
 | 
				
			||||||
        const data: ToolbarItemMap[K] = {
 | 
					        if (index !== -1) {
 | 
				
			||||||
            com: markRaw(comMap[item.type]),
 | 
					            console.warn(`添加了id重复的自定义工具,已将其覆盖`);
 | 
				
			||||||
            ...item
 | 
					            this.items[index] = item;
 | 
				
			||||||
        } as ToolbarItemMap[K];
 | 
					        } else {
 | 
				
			||||||
        this.items.push(data);
 | 
					            this.items.push(item);
 | 
				
			||||||
        this.emit('add', data);
 | 
					        }
 | 
				
			||||||
 | 
					        this.emit('add', item);
 | 
				
			||||||
        return this;
 | 
					        return this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -148,34 +160,21 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
 | 
				
			|||||||
        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('emit', id, item);
 | 
					        this.emit('emit', id, item);
 | 
				
			||||||
        if (item.type === 'hotkey') {
 | 
					        const info = CustomToolbar.info[item.type];
 | 
				
			||||||
            // 按键
 | 
					        if (!info) {
 | 
				
			||||||
            const assist = item.assist | this.assistKey;
 | 
					            console.warn(`触发了未知的自定义工具类型:'${item.type}'`);
 | 
				
			||||||
            const { ctrl, shift, alt } = unwarpBinary(assist);
 | 
					            return this;
 | 
				
			||||||
            const ev = new KeyboardEvent('keyup', {
 | 
					 | 
				
			||||||
                ctrlKey: ctrl,
 | 
					 | 
				
			||||||
                shiftKey: shift,
 | 
					 | 
				
			||||||
                altKey: alt
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // todo: Advanced KeyboardEvent simulate
 | 
					 | 
				
			||||||
            gameKey.emitKey(item.key, assist, 'up', ev);
 | 
					 | 
				
			||||||
        } else if (item.type === 'item') {
 | 
					 | 
				
			||||||
            // 道具
 | 
					 | 
				
			||||||
            core.tryUseItem(item.item);
 | 
					 | 
				
			||||||
        } else if (item.type === 'assistKey') {
 | 
					 | 
				
			||||||
            // 辅助按键
 | 
					 | 
				
			||||||
            if (item.assist === KeyCode.Ctrl) {
 | 
					 | 
				
			||||||
                this.assistKey = flipBinary(this.assistKey, 0);
 | 
					 | 
				
			||||||
            } else if (item.assist === KeyCode.Shift) {
 | 
					 | 
				
			||||||
                this.assistKey = flipBinary(this.assistKey, 1);
 | 
					 | 
				
			||||||
            } else if (item.assist === KeyCode.Alt) {
 | 
					 | 
				
			||||||
                this.assistKey = flipBinary(this.assistKey, 2);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        const success = info.onEmit.call(this, id, item);
 | 
				
			||||||
 | 
					        if (!success) {
 | 
				
			||||||
 | 
					            console.warn(`触发自定义工具失败,id:'${id}',type:${item.type}`);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return this;
 | 
					        return this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 强制刷新这个自定义工具栏的所有显示
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    refresh() {
 | 
					    refresh() {
 | 
				
			||||||
        const items = this.items.splice(0);
 | 
					        const items = this.items.splice(0);
 | 
				
			||||||
        nextTick(() => {
 | 
					        nextTick(() => {
 | 
				
			||||||
@ -194,15 +193,135 @@ export class CustomToolbar extends EventEmitter<CustomToolbarEvent> {
 | 
				
			|||||||
        has(height) && (this.height = height);
 | 
					        has(height) && (this.height = height);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 显示这个自定义工具栏,可以显示多个,且内容互通
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    show() {
 | 
					    show() {
 | 
				
			||||||
        fixedUi.open('toolbar', { bar: this });
 | 
					        const id = fixedUi.open('toolbar', { bar: this });
 | 
				
			||||||
 | 
					        this.showIds.push(id);
 | 
				
			||||||
 | 
					        return id;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 关闭一个以此实例为基础显示的自定义工具栏
 | 
				
			||||||
 | 
					     * @param id 要关闭的id
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    close(id: number) {
 | 
				
			||||||
 | 
					        fixedUi.close(id);
 | 
				
			||||||
 | 
					        deleteWith(this.showIds, id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 关闭这个自定义工具栏的所有显示
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    closeAll() {
 | 
				
			||||||
 | 
					        this.showIds.forEach(v => fixedUi.close(v));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static get(id: string) {
 | 
					    static get(id: string) {
 | 
				
			||||||
        return this.list.find(v => v.id === id);
 | 
					        return this.list.find(v => v.id === id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 注册一类自定义工具
 | 
				
			||||||
 | 
					     * @param type 要注册的自定义工具类型
 | 
				
			||||||
 | 
					     * @param name 该类型的中文名
 | 
				
			||||||
 | 
					     * @param onEmit 当触发这个自定义工具的时候执行的函数
 | 
				
			||||||
 | 
					     * @param show 这个自定义工具在自定义工具栏的显示组件
 | 
				
			||||||
 | 
					     * @param editor 这个自定义工具在编辑时编辑组件
 | 
				
			||||||
 | 
					     * @param onCreate 当这个自定义工具在编辑器中被添加时,执行的初始化脚本
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static register<K extends ToolbarItemType>(
 | 
				
			||||||
 | 
					        type: K,
 | 
				
			||||||
 | 
					        name: string,
 | 
				
			||||||
 | 
					        onEmit: ToolItemEmitFn<K>,
 | 
				
			||||||
 | 
					        show: CustomToolbarComponent<K>,
 | 
				
			||||||
 | 
					        editor: CustomToolbarComponent<K>,
 | 
				
			||||||
 | 
					        onCreate: (item: any) => ToolbarItemMap[K]
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        if (type in this.info) {
 | 
				
			||||||
 | 
					            console.warn(`已存在名为'${type}'的自定义工具类型,已将其覆盖!`);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        const info: RegisteredCustomToolInfo = {
 | 
				
			||||||
 | 
					            name,
 | 
				
			||||||
 | 
					            onEmit: onEmit as ToolItemEmitFn<ToolbarItemType>,
 | 
				
			||||||
 | 
					            show: show as CustomToolbarComponent,
 | 
				
			||||||
 | 
					            editor: editor as CustomToolbarComponent,
 | 
				
			||||||
 | 
					            // @ts-ignore
 | 
				
			||||||
 | 
					            onCreate
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        this.info[type] = info;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CustomToolbar.register(
 | 
				
			||||||
 | 
					    'hotkey',
 | 
				
			||||||
 | 
					    '快捷键',
 | 
				
			||||||
 | 
					    function (id, item) {
 | 
				
			||||||
 | 
					        // 按键
 | 
				
			||||||
 | 
					        const assist = item.assist | this.assistKey;
 | 
				
			||||||
 | 
					        const { ctrl, shift, alt } = unwarpBinary(assist);
 | 
				
			||||||
 | 
					        const ev = new KeyboardEvent('keyup', {
 | 
				
			||||||
 | 
					            ctrlKey: ctrl,
 | 
				
			||||||
 | 
					            shiftKey: shift,
 | 
				
			||||||
 | 
					            altKey: alt
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // todo: Advanced KeyboardEvent simulate
 | 
				
			||||||
 | 
					        gameKey.emitKey(item.key, assist, 'up', ev);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    COM.KeyTool,
 | 
				
			||||||
 | 
					    EDITOR.KeyTool,
 | 
				
			||||||
 | 
					    item => {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            key: KeyCode.Unknown,
 | 
				
			||||||
 | 
					            assist: 0,
 | 
				
			||||||
 | 
					            ...item
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					CustomToolbar.register(
 | 
				
			||||||
 | 
					    'item',
 | 
				
			||||||
 | 
					    '使用道具',
 | 
				
			||||||
 | 
					    function (id, item) {
 | 
				
			||||||
 | 
					        // 道具
 | 
				
			||||||
 | 
					        core.tryUseItem(item.item);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    COM.ItemTool,
 | 
				
			||||||
 | 
					    EDITOR.ItemTool,
 | 
				
			||||||
 | 
					    item => {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            item: 'book',
 | 
				
			||||||
 | 
					            ...item
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					CustomToolbar.register(
 | 
				
			||||||
 | 
					    'assistKey',
 | 
				
			||||||
 | 
					    '辅助按键',
 | 
				
			||||||
 | 
					    function (id, item) {
 | 
				
			||||||
 | 
					        // 辅助按键
 | 
				
			||||||
 | 
					        if (item.assist === KeyCode.Ctrl) {
 | 
				
			||||||
 | 
					            this.assistKey = flipBinary(this.assistKey, 0);
 | 
				
			||||||
 | 
					        } else if (item.assist === KeyCode.Shift) {
 | 
				
			||||||
 | 
					            this.assistKey = flipBinary(this.assistKey, 1);
 | 
				
			||||||
 | 
					        } else if (item.assist === KeyCode.Alt) {
 | 
				
			||||||
 | 
					            this.assistKey = flipBinary(this.assistKey, 2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    COM.AssistKeyTool,
 | 
				
			||||||
 | 
					    EDITOR.AssistKeyTool,
 | 
				
			||||||
 | 
					    item => {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            assist: KeyCode.Ctrl,
 | 
				
			||||||
 | 
					            ...item
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
hook.once('reset', () => {
 | 
					hook.once('reset', () => {
 | 
				
			||||||
    const toolbar = new CustomToolbar('test');
 | 
					    const toolbar = new CustomToolbar('test');
 | 
				
			||||||
    toolbar
 | 
					    toolbar
 | 
				
			||||||
 | 
				
			|||||||
@ -1,10 +1,13 @@
 | 
				
			|||||||
import { KeyCodeUtils } from '@/plugin/keyCodes';
 | 
					import { KeyCode, KeyCodeUtils } from '@/plugin/keyCodes';
 | 
				
			||||||
import type {
 | 
					import type {
 | 
				
			||||||
    CustomToolbarComponent,
 | 
					    CustomToolbarComponent,
 | 
				
			||||||
    CustomToolbarProps
 | 
					    CustomToolbarProps
 | 
				
			||||||
} from '../custom/toolbar';
 | 
					} from '../custom/toolbar';
 | 
				
			||||||
import BoxAnimate from '@/components/boxAnimate.vue';
 | 
					import BoxAnimate from '@/components/boxAnimate.vue';
 | 
				
			||||||
import { checkAssist } from '../custom/hotkey';
 | 
					import { checkAssist } from '../custom/hotkey';
 | 
				
			||||||
 | 
					import { getVitualKeyOnce } from '@/plugin/utils';
 | 
				
			||||||
 | 
					import { cloneDeep } from 'lodash-es';
 | 
				
			||||||
 | 
					import { Select, SelectOption } from 'ant-design-vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// todo: 新增更改设置的ToolItem
 | 
					// todo: 新增更改设置的ToolItem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -25,6 +28,16 @@ export function createToolbarComponents() {
 | 
				
			|||||||
    return com;
 | 
					    return com;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function createToolbarEditorComponents() {
 | 
				
			||||||
 | 
					    const com: Components = {
 | 
				
			||||||
 | 
					        DefaultTool: DefaultToolEditor,
 | 
				
			||||||
 | 
					        KeyTool: KeyToolEdtior,
 | 
				
			||||||
 | 
					        ItemTool: ItemToolEditor,
 | 
				
			||||||
 | 
					        AssistKeyTool: AssistKeyToolEditor
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    return com;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function DefaultTool(props: CustomToolbarProps) {
 | 
					function DefaultTool(props: CustomToolbarProps) {
 | 
				
			||||||
    return <span>未知工具</span>;
 | 
					    return <span>未知工具</span>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -70,3 +83,123 @@ function AssistKeyTool(props: CustomToolbarProps<'assistKey'>) {
 | 
				
			|||||||
        </span>
 | 
					        </span>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function DefaultToolEditor(props: CustomToolbarProps) {
 | 
				
			||||||
 | 
					    return <span></span>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function KeyToolEdtior(props: CustomToolbarProps<'hotkey'>) {
 | 
				
			||||||
 | 
					    const { item, toolbar } = props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const getKey = async () => {
 | 
				
			||||||
 | 
					        const { key, assist } = await getVitualKeyOnce(false, item.assist);
 | 
				
			||||||
 | 
					        toolbar.set<'hotkey'>(item.id, {
 | 
				
			||||||
 | 
					            key,
 | 
				
			||||||
 | 
					            assist
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const 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;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const getKeyShow = (key: KeyCode, assist: number) => {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            unwarpAssist(assist) +
 | 
				
			||||||
 | 
					            (key === KeyCode.Unknown ? '' : KeyCodeUtils.toString(key))
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					            style="
 | 
				
			||||||
 | 
					                display: flex; flex-direction: row; justify-content: space-between;
 | 
				
			||||||
 | 
					                align-items: center; padding: 0 5%; margin: 1%
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <span>触发按键</span>
 | 
				
			||||||
 | 
					            <span
 | 
				
			||||||
 | 
					                style="background-color: #000; width: 50%; text-align: end; padding: 0 5%"
 | 
				
			||||||
 | 
					                onClick={getKey}
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                {getKeyShow(item.key, item.assist)}
 | 
				
			||||||
 | 
					            </span>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function ItemToolEditor(props: CustomToolbarProps<'item'>) {
 | 
				
			||||||
 | 
					    const { item, toolbar } = props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const items = cloneDeep(core.status.hero.items.constants);
 | 
				
			||||||
 | 
					    Object.assign(items, core.status.hero.items.tools);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					            style="
 | 
				
			||||||
 | 
					                display: flex; flex-direction: row; justify-content: space-between;
 | 
				
			||||||
 | 
					                align-items: center; padding: 0 5%; margin: 1%
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <span>使用道具</span>
 | 
				
			||||||
 | 
					            <Select
 | 
				
			||||||
 | 
					                style="width: 180px; font-size: 80%; height: 100%; background-color: #000"
 | 
				
			||||||
 | 
					                value={item.item}
 | 
				
			||||||
 | 
					                onChange={value =>
 | 
				
			||||||
 | 
					                    toolbar.set<'item'>(item.id, {
 | 
				
			||||||
 | 
					                        item: value as ItemIdOf<'tools' | 'constants'>
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                {Object.entries(items).map(v => {
 | 
				
			||||||
 | 
					                    return (
 | 
				
			||||||
 | 
					                        <SelectOption value={v[0]}>
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                core.material.items[v[0] as AllIdsOf<'items'>]
 | 
				
			||||||
 | 
					                                    .name
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        </SelectOption>
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                })}
 | 
				
			||||||
 | 
					            </Select>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function AssistKeyToolEditor(props: CustomToolbarProps<'assistKey'>) {
 | 
				
			||||||
 | 
					    const { item, toolbar } = props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <div
 | 
				
			||||||
 | 
					            style="
 | 
				
			||||||
 | 
					               display: flex; flex-direction: row; justify-content: space-between;
 | 
				
			||||||
 | 
					               align-items: center; padding: 0 5%; margin: 1%
 | 
				
			||||||
 | 
					            "
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					            <span>辅助按键</span>
 | 
				
			||||||
 | 
					            <Select
 | 
				
			||||||
 | 
					                style="width: 180px; font-size: 80%; height: 100%; background-color: #000"
 | 
				
			||||||
 | 
					                value={item.assist}
 | 
				
			||||||
 | 
					                onChange={value =>
 | 
				
			||||||
 | 
					                    toolbar.set<'assistKey'>(item.id, {
 | 
				
			||||||
 | 
					                        assist: value as KeyCode.Ctrl
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                <SelectOption value={KeyCode.Ctrl}>Ctrl</SelectOption>
 | 
				
			||||||
 | 
					                <SelectOption value={KeyCode.Shift}>Shift</SelectOption>
 | 
				
			||||||
 | 
					                <SelectOption value={KeyCode.Alt}>Alt</SelectOption>
 | 
				
			||||||
 | 
					            </Select>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -356,7 +356,8 @@ export function flipBinary(num: number, col: number) {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
export function getVitualKeyOnce(
 | 
					export function getVitualKeyOnce(
 | 
				
			||||||
    emitAssist: boolean = false,
 | 
					    emitAssist: boolean = false,
 | 
				
			||||||
    assist: number = 0
 | 
					    assist: number = 0,
 | 
				
			||||||
 | 
					    emittable: KeyCode[] = []
 | 
				
			||||||
): Promise<KeyboardEmits> {
 | 
					): Promise<KeyboardEmits> {
 | 
				
			||||||
    return new Promise(res => {
 | 
					    return new Promise(res => {
 | 
				
			||||||
        const key = Keyboard.get('full')!;
 | 
					        const key = Keyboard.get('full')!;
 | 
				
			||||||
@ -365,11 +366,16 @@ export function getVitualKeyOnce(
 | 
				
			|||||||
        key.on('emit', (item, assist, index, ev) => {
 | 
					        key.on('emit', (item, assist, index, ev) => {
 | 
				
			||||||
            ev.preventDefault();
 | 
					            ev.preventDefault();
 | 
				
			||||||
            if (emitAssist) {
 | 
					            if (emitAssist) {
 | 
				
			||||||
 | 
					                if (emittable.length === 0 || emittable.includes(item.key)) {
 | 
				
			||||||
                    res({ key: item.key, assist: 0 });
 | 
					                    res({ key: item.key, assist: 0 });
 | 
				
			||||||
                    key.disposeScope();
 | 
					                    key.disposeScope();
 | 
				
			||||||
                    mainUi.close(id);
 | 
					                    mainUi.close(id);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if (!isAssist(item.key)) {
 | 
					                if (
 | 
				
			||||||
 | 
					                    !isAssist(item.key) &&
 | 
				
			||||||
 | 
					                    (emittable.length === 0 || emittable.includes(item.key))
 | 
				
			||||||
 | 
					                ) {
 | 
				
			||||||
                    res({ key: item.key, assist });
 | 
					                    res({ key: item.key, assist });
 | 
				
			||||||
                    key.disposeScope();
 | 
					                    key.disposeScope();
 | 
				
			||||||
                    mainUi.close(id);
 | 
					                    mainUi.close(id);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,9 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <Column :left="30" @close="exit">
 | 
					    <div id="tools">
 | 
				
			||||||
        <template #left>
 | 
					        <span class="button-text" @click="exit"><left-outlined /> 返回</span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div id="tool-editor">
 | 
				
			||||||
 | 
					        <Scroll class="tool-list-scroll">
 | 
				
			||||||
            <div id="tool-list">
 | 
					            <div id="tool-list">
 | 
				
			||||||
                <div
 | 
					                <div
 | 
				
			||||||
                    v-for="(item, i) of list"
 | 
					                    v-for="(item, i) of list"
 | 
				
			||||||
@ -12,48 +15,172 @@
 | 
				
			|||||||
                    <a-button
 | 
					                    <a-button
 | 
				
			||||||
                        type="danger"
 | 
					                        type="danger"
 | 
				
			||||||
                        class="tool-list-delete"
 | 
					                        class="tool-list-delete"
 | 
				
			||||||
                        @click.stop="deleteTool"
 | 
					                        @click.stop="deleteTool(item.id)"
 | 
				
			||||||
                        >删除</a-button
 | 
					                        >删除</a-button
 | 
				
			||||||
                    >
 | 
					                    >
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div id="tool-list-add">
 | 
					                <div id="tool-list-add">
 | 
				
			||||||
                    <div id="tool-add-div" @click="addTool">
 | 
					                    <div
 | 
				
			||||||
 | 
					                        id="tool-add-div"
 | 
				
			||||||
 | 
					                        @click="addingTool = true"
 | 
				
			||||||
 | 
					                        v-if="!addingTool"
 | 
				
			||||||
 | 
					                    >
 | 
				
			||||||
                        <PlusOutlined></PlusOutlined>  
 | 
					                        <PlusOutlined></PlusOutlined>  
 | 
				
			||||||
                        <span>新增工具栏</span>
 | 
					                        <span>新增工具栏</span>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div v-else>
 | 
				
			||||||
 | 
					                        <a-input
 | 
				
			||||||
 | 
					                            style="height: 100%; font-size: 80%; width: 100%"
 | 
				
			||||||
 | 
					                            v-model:value="addingToolId"
 | 
				
			||||||
 | 
					                            @blur="addTool"
 | 
				
			||||||
 | 
					                        ></a-input>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
        </template>
 | 
					            </div>
 | 
				
			||||||
        <template #right>
 | 
					        </Scroll>
 | 
				
			||||||
 | 
					        <a-divider
 | 
				
			||||||
 | 
					            class="divider"
 | 
				
			||||||
 | 
					            dashed
 | 
				
			||||||
 | 
					            style="border-color: #ddd4"
 | 
				
			||||||
 | 
					            :type="isMobile ? 'horizontal' : 'vertical'"
 | 
				
			||||||
 | 
					        ></a-divider>
 | 
				
			||||||
        <div id="tool-info">
 | 
					        <div id="tool-info">
 | 
				
			||||||
                <div id="tool-detail"></div>
 | 
					            <div id="tool-detail">
 | 
				
			||||||
 | 
					                <Scroll class="tool-item-list-scroll">
 | 
				
			||||||
 | 
					                    <div class="tool-item-list">
 | 
				
			||||||
 | 
					                        <div
 | 
				
			||||||
 | 
					                            class="tool-item-list-item"
 | 
				
			||||||
 | 
					                            v-for="item of bar.items"
 | 
				
			||||||
 | 
					                        >
 | 
				
			||||||
 | 
					                            <div
 | 
				
			||||||
 | 
					                                class="tool-item-header"
 | 
				
			||||||
 | 
					                                :folded="!unfolded[item.id]"
 | 
				
			||||||
 | 
					                                @click="triggerFold(item.id)"
 | 
				
			||||||
 | 
					                            >
 | 
				
			||||||
 | 
					                                <div
 | 
				
			||||||
 | 
					                                    style="
 | 
				
			||||||
 | 
					                                        display: flex;
 | 
				
			||||||
 | 
					                                        flex-direction: row;
 | 
				
			||||||
 | 
					                                        width: 100%;
 | 
				
			||||||
 | 
					                                    "
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                                    <span
 | 
				
			||||||
 | 
					                                        class="tool-fold"
 | 
				
			||||||
 | 
					                                        :folded="!unfolded[item.id]"
 | 
				
			||||||
 | 
					                                    >
 | 
				
			||||||
 | 
					                                        <RightOutlined></RightOutlined>
 | 
				
			||||||
 | 
					                                    </span>
 | 
				
			||||||
 | 
					                                    <span class="tool-name">
 | 
				
			||||||
 | 
					                                        <span
 | 
				
			||||||
 | 
					                                            v-if="editId !== item.id"
 | 
				
			||||||
 | 
					                                            style="cursor: text"
 | 
				
			||||||
 | 
					                                            @click.stop="editName(item.id)"
 | 
				
			||||||
 | 
					                                        >
 | 
				
			||||||
 | 
					                                            {{ item.id }}
 | 
				
			||||||
 | 
					                                        </span>
 | 
				
			||||||
 | 
					                                        <span v-else>
 | 
				
			||||||
 | 
					                                            <a-input
 | 
				
			||||||
 | 
					                                                @blur="editNameSuccess(item.id)"
 | 
				
			||||||
 | 
					                                                @click.stop=""
 | 
				
			||||||
 | 
					                                                v-model:value="editValue"
 | 
				
			||||||
 | 
					                                                class="tool-name-edit"
 | 
				
			||||||
 | 
					                                            ></a-input>
 | 
				
			||||||
 | 
					                                        </span>
 | 
				
			||||||
 | 
					                                    </span>
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                <a-button
 | 
				
			||||||
 | 
					                                    type="danger"
 | 
				
			||||||
 | 
					                                    class="tool-item-delete"
 | 
				
			||||||
 | 
					                                    @click.stop="deleteItem(item)"
 | 
				
			||||||
 | 
					                                    >删除</a-button
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <div v-if="!!unfolded[item.id]">
 | 
				
			||||||
 | 
					                                <component
 | 
				
			||||||
 | 
					                                    :is="CustomToolbar.info[item.type].editor"
 | 
				
			||||||
 | 
					                                    :item="item"
 | 
				
			||||||
 | 
					                                    :toolbar="bar"
 | 
				
			||||||
 | 
					                                ></component>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <div id="tool-item-add">
 | 
				
			||||||
 | 
					                            <div
 | 
				
			||||||
 | 
					                                id="tool-item-add-div"
 | 
				
			||||||
 | 
					                                v-if="!addingItem"
 | 
				
			||||||
 | 
					                                @click="addingItem = true"
 | 
				
			||||||
 | 
					                            >
 | 
				
			||||||
 | 
					                                <PlusOutlined></PlusOutlined>  
 | 
				
			||||||
 | 
					                                <span>新增工具</span>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <div id="tool-item-add-type" v-else>
 | 
				
			||||||
 | 
					                                <span>工具类型</span>
 | 
				
			||||||
 | 
					                                <a-select
 | 
				
			||||||
 | 
					                                    v-model:value="addingType"
 | 
				
			||||||
 | 
					                                    style="
 | 
				
			||||||
 | 
					                                        width: 120px;
 | 
				
			||||||
 | 
					                                        height: 100%;
 | 
				
			||||||
 | 
					                                        font-size: 80%;
 | 
				
			||||||
 | 
					                                        background-color: #222;
 | 
				
			||||||
 | 
					                                    "
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                                    <a-select-option
 | 
				
			||||||
 | 
					                                        v-for="(
 | 
				
			||||||
 | 
					                                            info, type
 | 
				
			||||||
 | 
					                                        ) of CustomToolbar.info"
 | 
				
			||||||
 | 
					                                        :value="type"
 | 
				
			||||||
 | 
					                                        >{{ info.name }}</a-select-option
 | 
				
			||||||
 | 
					                                    >
 | 
				
			||||||
 | 
					                                </a-select>
 | 
				
			||||||
 | 
					                                <a-button
 | 
				
			||||||
 | 
					                                    type="primary"
 | 
				
			||||||
 | 
					                                    style="font-size: 80%; height: 100%"
 | 
				
			||||||
 | 
					                                    @click="addItem(true)"
 | 
				
			||||||
 | 
					                                    >确定</a-button
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                                <a-button
 | 
				
			||||||
 | 
					                                    @click="addItem(false)"
 | 
				
			||||||
 | 
					                                    style="
 | 
				
			||||||
 | 
					                                        background-color: #222;
 | 
				
			||||||
 | 
					                                        font-size: 80%;
 | 
				
			||||||
 | 
					                                        height: 100%;
 | 
				
			||||||
 | 
					                                    "
 | 
				
			||||||
 | 
					                                    >取消</a-button
 | 
				
			||||||
 | 
					                                >
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </Scroll>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
            <a-divider dashed></a-divider>
 | 
					            <a-divider dashed></a-divider>
 | 
				
			||||||
            <div id="tool-preview">
 | 
					            <div id="tool-preview">
 | 
				
			||||||
                <div id="tool-preview-container">
 | 
					                <div id="tool-preview-container">
 | 
				
			||||||
                        <div
 | 
					                    <div class="tool-preview-item" v-for="item of bar.items">
 | 
				
			||||||
                            class="tool-preview-item"
 | 
					 | 
				
			||||||
                            v-for="item of bar.items"
 | 
					 | 
				
			||||||
                        >
 | 
					 | 
				
			||||||
                        <component
 | 
					                        <component
 | 
				
			||||||
                                :is="(item.com as any)"
 | 
					                            :is="(CustomToolbar.info[item.type].show as any)"
 | 
				
			||||||
                            :item="item"
 | 
					                            :item="item"
 | 
				
			||||||
                                :bar="bar"
 | 
					                            :toolbar="bar"
 | 
				
			||||||
                        ></component>
 | 
					                        ></component>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        </template>
 | 
					    </div>
 | 
				
			||||||
    </Column>
 | 
					 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script lang="ts" setup>
 | 
					<script lang="ts" setup>
 | 
				
			||||||
import { CustomToolbar } from '@/core/main/custom/toolbar';
 | 
					import { CustomToolbar, ToolbarItemType } from '@/core/main/custom/toolbar';
 | 
				
			||||||
import { GameUi } from '@/core/main/custom/ui';
 | 
					import { GameUi } from '@/core/main/custom/ui';
 | 
				
			||||||
import Column from '../components/colomn.vue';
 | 
					import { computed, reactive, ref } from 'vue';
 | 
				
			||||||
import { computed, ref } from 'vue';
 | 
					import {
 | 
				
			||||||
import { PlusOutlined } from '@ant-design/icons-vue';
 | 
					    PlusOutlined,
 | 
				
			||||||
 | 
					    RightOutlined,
 | 
				
			||||||
 | 
					    LeftOutlined
 | 
				
			||||||
 | 
					} from '@ant-design/icons-vue';
 | 
				
			||||||
import { mainUi } from '@/core/main/init/ui';
 | 
					import { mainUi } from '@/core/main/init/ui';
 | 
				
			||||||
 | 
					import { isMobile } from '@/plugin/use';
 | 
				
			||||||
 | 
					import Scroll from '@/components/scroll.vue';
 | 
				
			||||||
 | 
					import { deleteWith, tip } from '@/plugin/utils';
 | 
				
			||||||
 | 
					import { Modal } from 'ant-design-vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps<{
 | 
					const props = defineProps<{
 | 
				
			||||||
    ui: GameUi;
 | 
					    ui: GameUi;
 | 
				
			||||||
@ -65,25 +192,148 @@ const list = CustomToolbar.list;
 | 
				
			|||||||
const selected = ref(0);
 | 
					const selected = ref(0);
 | 
				
			||||||
const bar = computed(() => list[selected.value]);
 | 
					const bar = computed(() => list[selected.value]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const unfolded = reactive<Record<string, boolean>>({});
 | 
				
			||||||
 | 
					const editId = ref<string>();
 | 
				
			||||||
 | 
					const editValue = ref<string>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 添加自定义工具
 | 
				
			||||||
 | 
					const addingItem = ref(false);
 | 
				
			||||||
 | 
					const addingType = ref<ToolbarItemType>('item');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 添加自定义工具栏
 | 
				
			||||||
 | 
					const addingTool = ref(false);
 | 
				
			||||||
 | 
					const addingToolId = ref('');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 编辑名称
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function editName(id: string) {
 | 
				
			||||||
 | 
					    editId.value = id;
 | 
				
			||||||
 | 
					    editValue.value = id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 编辑名称完成
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function editNameSuccess(id: string) {
 | 
				
			||||||
 | 
					    if (bar.value.items.some(v => v.id === editId.value)) {
 | 
				
			||||||
 | 
					        tip('error', '名称重复!');
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        const item = bar.value.items.find(v => v.id === id)!;
 | 
				
			||||||
 | 
					        item.id = editValue.value!;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    editId.value = void 0;
 | 
				
			||||||
 | 
					    editValue.value = void 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 删除自定义工具
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function deleteItem(item: any) {
 | 
				
			||||||
 | 
					    Modal.confirm({
 | 
				
			||||||
 | 
					        title: '确定要删除这个自定义工具吗?',
 | 
				
			||||||
 | 
					        onOk() {
 | 
				
			||||||
 | 
					            deleteWith(bar.value.items, item);
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        onCancel() {}
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function addItem(add: boolean) {
 | 
				
			||||||
 | 
					    if (add) {
 | 
				
			||||||
 | 
					        bar.value.add(
 | 
				
			||||||
 | 
					            // @ts-ignore
 | 
				
			||||||
 | 
					            CustomToolbar.info[addingType.value].onCreate({
 | 
				
			||||||
 | 
					                id: `tool-item-${bar.value.items.length}`,
 | 
				
			||||||
 | 
					                type: addingType.value
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    addingItem.value = false;
 | 
				
			||||||
 | 
					    addingType.value = 'item';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * 更改折叠
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					function triggerFold(id: string) {
 | 
				
			||||||
 | 
					    unfolded[id] = !unfolded[id];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function exit() {
 | 
					function exit() {
 | 
				
			||||||
    mainUi.close(props.num);
 | 
					    mainUi.close(props.num);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function deleteTool() {}
 | 
					function deleteTool(id: string) {
 | 
				
			||||||
 | 
					    Modal.confirm({
 | 
				
			||||||
 | 
					        title: '确定要删除这个自定义工具栏吗?',
 | 
				
			||||||
 | 
					        onOk() {
 | 
				
			||||||
 | 
					            const index = CustomToolbar.list.findIndex(v => v.id === id);
 | 
				
			||||||
 | 
					            if (index !== -1) {
 | 
				
			||||||
 | 
					                CustomToolbar.list[index].closeAll();
 | 
				
			||||||
 | 
					                CustomToolbar.list.splice(index, 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            selected.value = 0;
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        onCancel() {}
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function addTool() {}
 | 
					function addTool() {
 | 
				
			||||||
 | 
					    if (addingToolId.value === '') {
 | 
				
			||||||
 | 
					        addingToolId.value = '';
 | 
				
			||||||
 | 
					        addingTool.value = false;
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (CustomToolbar.list.some(v => v.id === addingToolId.value)) {
 | 
				
			||||||
 | 
					        tip('error', '工具栏名称重复!');
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        const bar = new CustomToolbar(addingToolId.value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    addingToolId.value = '';
 | 
				
			||||||
 | 
					    addingTool.value = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="less" scoped>
 | 
					<style lang="less" scoped>
 | 
				
			||||||
 | 
					#tools {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    font-family: 'normal';
 | 
				
			||||||
 | 
					    font-size: 3.2vh;
 | 
				
			||||||
 | 
					    height: 5vh;
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    left: 10vw;
 | 
				
			||||||
 | 
					    top: 5vh;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#tool-editor {
 | 
				
			||||||
 | 
					    width: 70%;
 | 
				
			||||||
 | 
					    height: 70%;
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					    justify-content: center;
 | 
				
			||||||
 | 
					    align-items: center;
 | 
				
			||||||
 | 
					    font-family: 'normal';
 | 
				
			||||||
 | 
					    font-size: 150%;
 | 
				
			||||||
 | 
					    user-select: none;
 | 
				
			||||||
 | 
					    align-self: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.tool-list-item {
 | 
					.tool-list-item {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: center;
 | 
				
			||||||
    justify-content: space-between;
 | 
					    justify-content: space-between;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.tool-list-scroll {
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    width: 30%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#tool-list {
 | 
					#tool-list {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    flex-direction: column;
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#tool-list-add {
 | 
					#tool-list-add {
 | 
				
			||||||
@ -119,22 +369,140 @@ function addTool() {}
 | 
				
			|||||||
#tool-info {
 | 
					#tool-info {
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    flex-direction: column;
 | 
					    flex-direction: column;
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    width: 70%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#tool-detail {
 | 
				
			||||||
 | 
					    height: 60%;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-item-header {
 | 
				
			||||||
 | 
					        cursor: pointer;
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					        flex-direction: row;
 | 
				
			||||||
 | 
					        align-items: center;
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-item-header[folded='false'] {
 | 
				
			||||||
 | 
					        border-bottom: 0.5px solid #888;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-item-list-scroll {
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-item-list {
 | 
				
			||||||
 | 
					        width: 100%;
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					        flex-direction: column;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-item-list-item {
 | 
				
			||||||
 | 
					        border: 1px solid #ddd8;
 | 
				
			||||||
 | 
					        margin-bottom: 5%;
 | 
				
			||||||
 | 
					        background-color: #222;
 | 
				
			||||||
 | 
					        padding-left: 2%;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-fold {
 | 
				
			||||||
 | 
					        ::v-deep(span) {
 | 
				
			||||||
 | 
					            transition: all 0.2s ease;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-fold[folded='false'] {
 | 
				
			||||||
 | 
					        ::v-deep(span) {
 | 
				
			||||||
 | 
					            transform: rotate(90deg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-name {
 | 
				
			||||||
 | 
					        margin-left: 3%;
 | 
				
			||||||
 | 
					        width: 40%;
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .tool-name-edit {
 | 
				
			||||||
 | 
					            width: 100%;
 | 
				
			||||||
 | 
					            font-size: 100%;
 | 
				
			||||||
 | 
					            height: 100%;
 | 
				
			||||||
 | 
					            background-color: #000;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .tool-item-delete {
 | 
				
			||||||
 | 
					        height: 100%;
 | 
				
			||||||
 | 
					        justify-self: end;
 | 
				
			||||||
 | 
					        font-size: 80%;
 | 
				
			||||||
 | 
					        padding: 2px 15px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #tool-item-add-div {
 | 
				
			||||||
 | 
					        padding: 1% 3% 1% 3%;
 | 
				
			||||||
 | 
					        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-item-add-div:hover {
 | 
				
			||||||
 | 
					        background-color: rgba(39, 251, 209, 0.316);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #tool-item-add-div:active {
 | 
				
			||||||
 | 
					        background-color: rgba(39, 251, 209, 0.202);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #tool-item-add-type {
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					        align-items: center;
 | 
				
			||||||
 | 
					        flex-direction: row;
 | 
				
			||||||
 | 
					        padding: 1% 4%;
 | 
				
			||||||
 | 
					        justify-content: space-between;
 | 
				
			||||||
 | 
					        border-radius: 5px;
 | 
				
			||||||
 | 
					        background-color: rgba(39, 251, 209, 0.316);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#tool-preview {
 | 
					#tool-preview {
 | 
				
			||||||
 | 
					    height: 40%;
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    justify-content: center;
 | 
					    justify-content: center;
 | 
				
			||||||
    align-items: center;
 | 
					    align-items: start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #tool-preview-container {
 | 
					    #tool-preview-container {
 | 
				
			||||||
 | 
					        width: 90%;
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					        flex-direction: row;
 | 
				
			||||||
        border: 2px solid #ddd9;
 | 
					        border: 2px solid #ddd9;
 | 
				
			||||||
        background-color: #0009;
 | 
					        background-color: #0009;
 | 
				
			||||||
 | 
					        flex-wrap: wrap;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .tool-preview-item {
 | 
					    .tool-preview-item {
 | 
				
			||||||
 | 
					        display: flex;
 | 
				
			||||||
 | 
					        margin: 5px;
 | 
				
			||||||
 | 
					        min-width: 50px;
 | 
				
			||||||
 | 
					        height: 50px;
 | 
				
			||||||
 | 
					        background-color: #222;
 | 
				
			||||||
 | 
					        border: 1.5px solid #ddd8;
 | 
				
			||||||
 | 
					        justify-content: center;
 | 
				
			||||||
 | 
					        align-items: center;
 | 
				
			||||||
 | 
					        transition: all 0.1s linear;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ::v-deep(*) {
 | 
					        ::v-deep(*) {
 | 
				
			||||||
            pointer-events: none;
 | 
					            pointer-events: none;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.divider {
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
</style>
 | 
					</style>
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,7 @@
 | 
				
			|||||||
                @click.stop="click"
 | 
					                @click.stop="click"
 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
                <component
 | 
					                <component
 | 
				
			||||||
                    :is="(item.com as any)"
 | 
					                    :is="(CustomToolbar.info[item.type].show as any)"
 | 
				
			||||||
                    :item="item"
 | 
					                    :item="item"
 | 
				
			||||||
                    :toolbar="bar"
 | 
					                    :toolbar="bar"
 | 
				
			||||||
                ></component>
 | 
					                ></component>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user