diff --git a/src/customDefine/event.ts b/src/customDefine/event.ts index e814cca..904790c 100644 --- a/src/customDefine/event.ts +++ b/src/customDefine/event.ts @@ -20,16 +20,23 @@ type EventArg = { desc: string; }; +export type Folder = { + name: string; + childs: { [key: string]: Event | Folder }; +}; + export class Events extends BaseDefine { constructor() { super(); this.onDidChange(() => { this._eventsCache = undefined; + this._folderCache = undefined; }); } private _eventsCache?: Event[]; + private _folderCache?: Folder; get watchPattern() { if (!env.mapUri) { @@ -104,9 +111,38 @@ export class Events extends BaseDefine { } public async getEvents() { - if (!this._eventsCache) { - this._eventsCache = await this.loadEvents(); + return this._eventsCache ??= await this.loadEvents(); + } + + private async loadEventsFolder() { + let root: Folder = { + name: '', + childs: {}, + }; + + let events = await this.getEvents(); + + function getFolder(fullPath: string[]) { + let folder = root; + for (const path of fullPath) { + folder.childs[path] ??= { + name: path, + childs: {}, + }; + folder = folder.childs[path] as Folder; + } + return folder; + } + + for (const event of events) { + let folder = getFolder(event.path); + folder.childs[event.name] = event; } - return this._eventsCache; + + return root; + } + + public async getEventsFolder() { + return this._folderCache ??= await this.loadEventsFolder(); } } diff --git a/src/mainMenu/pages/events.ts b/src/mainMenu/pages/events.ts index 18e2ca6..d15ac92 100644 --- a/src/mainMenu/pages/events.ts +++ b/src/mainMenu/pages/events.ts @@ -2,35 +2,84 @@ import { TreeNode } from "../treeNode"; import * as vscode from 'vscode'; import { define } from "../../customDefine"; import { env } from "../../env"; +import * as Events from "../../customDefine/event"; export class 自定义事件 extends TreeNode { constructor() { + let mode = 'list'; super('自定义事件', { iconPath: new vscode.ThemeIcon('group-by-ref-type'), + + command: { + command: 'y3-helper.changeEventMode', + title: '切换显示模式', + }, + show: async () => { await env.mapReady(); return env.projectUri !== undefined; }, update: async (node) => { - node.childs = (await define.自定义事件.getEvents()).map(event => { - let args = event.args.map(arg => arg.name); - return new TreeNode(event.name, { - iconPath: new vscode.ThemeIcon('symbol-event'), - description: `${event.id.toString()}(${args.join(',')})`, - contextValue: '自定义事件', - data: event.id, - childs: event.args.map(arg => new TreeNode(arg.name, { - description: `${arg.desc}(${arg.luaType})`, - })), + node.description = mode === 'list' + ? '平铺模式(点击切换)' + : '文件夹模式(点击切换)'; + if (mode === 'list') { + node.childs = (await define.自定义事件.getEvents()).map(event => { + let args = event.args.map(arg => arg.name); + return new TreeNode(event.name, { + iconPath: new vscode.ThemeIcon('symbol-event'), + description: `${event.id.toString()}(${args.join(',')})`, + contextValue: '自定义事件', + data: event.id, + childs: args.length > 0 ? event.args.map(arg => new TreeNode(arg.name, { + description: `${arg.desc}(${arg.luaType})`, + })) : undefined, + }); }); - }); + } + if (mode === 'tree') { + function makeChilds(folder: Events.Folder) { + return Object.entries(folder.childs).map(([name, event]) => { + if ('childs' in event) { + return new TreeNode(name, { + iconPath: new vscode.ThemeIcon('folder'), + update: async (node) => { + node.childs = makeChilds(event); + } + }); + } else { + let args = event.args.map(arg => arg.name); + return new TreeNode(name, { + iconPath: new vscode.ThemeIcon('symbol-event'), + description: `${event.id.toString()}(${args.join(',')})`, + contextValue: '自定义事件', + data: event.id, + childs: args.length > 0 ? event.args.map(arg => new TreeNode(arg.name, { + description: `${arg.desc}(${arg.luaType})`, + })) : undefined, + }); + } + }); + } + + node.childs = makeChilds(await define.自定义事件.getEventsFolder()); + } }, }); define.自定义事件.onDidChange(() => { this.refresh(); }); + + vscode.commands.registerCommand('y3-helper.changeEventMode', () => { + if (mode === 'list') { + mode = 'tree'; + } else { + mode = 'list'; + } + this.refresh(); + }); } };