From fed08a0f45294d00860fa0a512d3cf8b58becc0e Mon Sep 17 00:00:00 2001 From: codetypes Date: Wed, 13 Mar 2024 00:28:37 +0800 Subject: [PATCH] double click to edit subtree --- common/Utils.ts | 27 +------- main-process/AppMenu.ts | 28 ++++---- main-process/MainProcess.tsx | 14 +++- render-process/Editor/NodePanel.tsx | 59 +++++++++++----- render-process/Editor/index.tsx | 100 +++++++++++++++++++--------- render-process/RegisterNode.ts | 31 ++++----- render-process/TreeTabs.tsx | 16 ++++- sample/workdir/monster.json | 1 + sample/workdir/subtree2.json | 8 +++ 9 files changed, 176 insertions(+), 108 deletions(-) diff --git a/common/Utils.ts b/common/Utils.ts index 3c43d53..2f5d4b3 100644 --- a/common/Utils.ts +++ b/common/Utils.ts @@ -1,9 +1,8 @@ -import { TreeGraph } from "@antv/g6"; -import * as path from "path"; +import { message } from "antd"; import * as fs from "fs"; +import * as path from "path"; import Settings from "../main-process/Settings"; import { BehaviorNodeModel, BehaviorTreeModel, GraphNodeModel } from "./BehaviorTreeModel"; -import { message } from "antd"; interface INodeDataLike { path?: string; @@ -165,28 +164,6 @@ export const createFileData = (gNode: GraphNodeModel, includeSubtree?: boolean) return nodeData; }; -export const findParent = (graph: TreeGraph, node: GraphNodeModel) => { - if (node.parent) { - return graph.findDataById(node.parent); - } else { - return null; - } -}; - -export const isAncestor = ( - graph: TreeGraph, - ancestor: GraphNodeModel, - node: GraphNodeModel -): boolean => { - if (ancestor.id === node.parent) { - return true; - } else if (node.parent) { - return isAncestor(graph, ancestor, graph.findDataById(node.parent) as GraphNodeModel); - } else { - return false; - } -}; - export const getRemoteSettings = () => { return require("@electron/remote").getGlobal("settings") as Settings; }; diff --git a/main-process/AppMenu.ts b/main-process/AppMenu.ts index 6d7b5ea..354a5c1 100644 --- a/main-process/AppMenu.ts +++ b/main-process/AppMenu.ts @@ -55,7 +55,7 @@ export default class AppMenu { submenu: [ { label: "新建", - accelerator: "CommandOrControl+n", + accelerator: "CmdOrCtrl+n", click: () => { (async () => { const res = await dialog.showSaveDialog({ @@ -75,7 +75,7 @@ export default class AppMenu { }, { label: "打开文件", - accelerator: "CommandOrControl+O", + accelerator: "CmdOrCtrl+O", click: () => { (async () => { const res = await dialog.showOpenDialog({ @@ -103,14 +103,14 @@ export default class AppMenu { { type: "separator" }, { label: "保存", - accelerator: "CommandOrControl+s", + accelerator: "CmdOrCtrl+s", click: () => { this.webContents.send(MainEventType.SAVE); }, }, { label: "全部保存", - accelerator: "CommandOrControl+shift+s", + accelerator: "CmdOrCtrl+shift+s", click: () => { this.webContents.send(MainEventType.SAVE_ALL); }, @@ -139,7 +139,7 @@ export default class AppMenu { }, { label: "构建", - accelerator: "CommandOrControl+b", + accelerator: "CmdOrCtrl+b", click: async () => { if (!this.buildDir) { const res = await dialog.showOpenDialog({ @@ -163,17 +163,13 @@ export default class AppMenu { submenu: [ { label: "撤销", - accelerator: "CommandOrControl+z", - click: () => { - this.webContents.send(MainEventType.UNDO); - }, + accelerator: "CmdOrCtrl+z", + role: "undo", }, { label: "恢复", - accelerator: "CommandOrControl+y", - click: () => { - this.webContents.send(MainEventType.REDO); - }, + accelerator: process.platform === "darwin" ? "cmd+shift+z" : "ctrl+y", + role: "redo", }, { type: "separator" }, { @@ -287,7 +283,7 @@ export default class AppMenu { { type: "separator" }, { label: "打开目录", - accelerator: "CommandOrControl+Shift+O", + accelerator: "CmdOrCtrl+Shift+O", click: () => { if (!this.settings.curWorkspace.getNodeConfPath()) { dialog.showErrorBox("警告", "请先指定节点定义配置!"); @@ -364,7 +360,7 @@ export default class AppMenu { submenu: [ { label: "热更", - accelerator: "CommandOrControl+R", + accelerator: "CmdOrCtrl+R", click: () => { this.webContents.send(MainEventType.RELOAD_SERVER); }, @@ -392,7 +388,7 @@ export default class AppMenu { }, { label: "打开控制台", - accelerator: "CommandOrControl+Shift+I", + accelerator: "CmdOrCtrl+Shift+I", click: (_, browserWindow) => { browserWindow.webContents.toggleDevTools(); }, diff --git a/main-process/MainProcess.tsx b/main-process/MainProcess.tsx index 94269df..19c9db6 100644 --- a/main-process/MainProcess.tsx +++ b/main-process/MainProcess.tsx @@ -18,12 +18,18 @@ export class MainProcess { nativeTheme.themeSource = "dark"; app.on("ready", () => { this.createWindow(); - electronLocalshortcut.register(this.mainWindow, "CommandOrControl+C", () => { + this.registerShortcut("CmdOrCtrl+C", () => { this.mainWindow.webContents.send(MainEventType.COPY_NODE); }); - electronLocalshortcut.register(this.mainWindow, "CommandOrControl+V", () => { + this.registerShortcut("CmdOrCtrl+V", () => { this.mainWindow.webContents.send(MainEventType.PASTE_NODE); }); + this.registerShortcut("CmdOrCtrl+Z", () => { + this.mainWindow.webContents.send(MainEventType.UNDO); + }); + this.registerShortcut(process.platform === "darwin" ? "Cmd+Shift+Z" : "ctrl+y", () => { + this.mainWindow.webContents.send(MainEventType.REDO); + }); }); app.on("window-all-closed", () => { if (process.platform !== "darwin") { @@ -37,6 +43,10 @@ export class MainProcess { }); } + registerShortcut(accelerator: string | string[], callback: () => void) { + electronLocalshortcut.register(this.mainWindow, accelerator, callback); + } + createWindow() { this.settings = new Settings(); global.settings = this.settings; diff --git a/render-process/Editor/NodePanel.tsx b/render-process/Editor/NodePanel.tsx index 1a07ce9..79875f2 100644 --- a/render-process/Editor/NodePanel.tsx +++ b/render-process/Editor/NodePanel.tsx @@ -25,6 +25,7 @@ const { Item } = Form; const { Option } = Select; interface NodePanelProps { + isSubtreeNode: boolean; model: BehaviorNodeModel; settings: Settings; updateNode: (id: string, forceUpdate: boolean) => void; @@ -151,7 +152,7 @@ export default class NodePanel extends React.Component { }; render() { - const { model, settings } = this.props; + const { model, settings, isSubtreeNode } = this.props; const conf = settings.getNodeConf(model.name); const title = conf.desc; @@ -178,6 +179,7 @@ export default class NodePanel extends React.Component { { @@ -189,24 +191,24 @@ export default class NodePanel extends React.Component { /> - + - + - + - {this.renderInputs(conf)} - {this.renderArgs(conf)} - {this.renderOutputs(conf)} + {this.renderInputs(conf, isSubtreeNode)} + {this.renderArgs(conf, isSubtreeNode)} + {this.renderOutputs(conf, isSubtreeNode)} ); } - renderArgs(conf: BehaviorNodeTypeModel) { + renderArgs(conf: BehaviorNodeTypeModel, isSubtreeNode: boolean) { if (!conf || !conf.args || conf.args.length == 0) { return null; } @@ -215,24 +217,41 @@ export default class NodePanel extends React.Component { const normalArgs = (e: ArgsDefType) => { const required = e.type.indexOf("?") == -1; if (e.type.indexOf("string") >= 0) { - return ; + return ; } else if (e.type.indexOf("int") >= 0) { return ( ); } else if (e.type.indexOf("float") >= 0) { - return ; + return ( + + ); } else if (e.type.indexOf("boolean") >= 0) { - return ; + return ; } else if (e.type.indexOf("code") >= 0) { - return ; + return ( + + ); } else if (e.type.indexOf("enum") >= 0) { return ( - {e.options.map((e) => { return (