style: format codes
This commit is contained in:
1 parent
c3ea18e307
commit
00e79d641e
14 files changed
+2152
-2186
No files matched your search
+375
-375
@@ -1,375 +1,375 @@
|
||||
import {
|
||||
Menu,
|
||||
app,
|
||||
dialog,
|
||||
BrowserWindow,
|
||||
MenuItem,
|
||||
WebContents,
|
||||
MenuItemConstructorOptions,
|
||||
} from "electron";
|
||||
import * as fs from "fs";
|
||||
import * as Utils from "../common/Utils";
|
||||
import MainEventType from "../common/MainEventType";
|
||||
import { MainProcess } from "./MainProcess";
|
||||
import Settings from "./Settings";
|
||||
|
||||
export default class AppMenu {
|
||||
private mainProcess: MainProcess;
|
||||
private mainWindow: BrowserWindow;
|
||||
private webContents: WebContents;
|
||||
private settings: Settings;
|
||||
|
||||
constructor(mainProcess: MainProcess) {
|
||||
this.mainProcess = mainProcess;
|
||||
this.mainWindow = mainProcess.mainWindow;
|
||||
this.webContents = mainProcess.mainWindow.webContents;
|
||||
this.settings = mainProcess.settings;
|
||||
}
|
||||
|
||||
createMenu() {
|
||||
const menu: Menu = new Menu();
|
||||
menu.append(this.createWorkspaceMenu());
|
||||
menu.append(this.createFileMenu());
|
||||
menu.append(this.createNodeMenu());
|
||||
menu.append(this.createToolsMenu());
|
||||
return menu;
|
||||
}
|
||||
|
||||
private createFileMenu() {
|
||||
const fileItems: MenuItemConstructorOptions[] = [];
|
||||
for (let path of this.settings.recentFiles) {
|
||||
fileItems.push({
|
||||
label: path,
|
||||
click: () => {
|
||||
console.log("open recent file", path);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return new MenuItem({
|
||||
label: "行为树",
|
||||
submenu: [
|
||||
{
|
||||
label: "新建",
|
||||
accelerator: "ctrl+n",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (!res.canceled) {
|
||||
const path = res.filePath;
|
||||
fs.writeFileSync(
|
||||
path,
|
||||
JSON.stringify(Utils.createNewTree(path), null, 2)
|
||||
);
|
||||
this.webContents.send(MainEventType.CREATE_TREE, path);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "打开文件",
|
||||
accelerator: "Ctrl+O",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const path = res.filePaths[0];
|
||||
if (this.settings.recentFiles.indexOf(path) < 0) {
|
||||
this.settings.recentFiles.unshift(path);
|
||||
this.settings.save();
|
||||
this.mainProcess.rebuildMenu();
|
||||
}
|
||||
this.webContents.send(MainEventType.OPEN_FILE, path);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "最近打开",
|
||||
submenu: fileItems,
|
||||
},
|
||||
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "保存",
|
||||
accelerator: "ctrl+s",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.SAVE);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "全部保存",
|
||||
accelerator: "ctrl+shift+s",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.SAVE_ALL);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "合并导出Json",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePath) {
|
||||
const curWorkspace = this.settings.curWorkspace;
|
||||
curWorkspace.writeAllTrees(res.filePath,(err)=>{
|
||||
const msg = err?err:"导出成功";
|
||||
dialog.showMessageBox({
|
||||
type:"info",
|
||||
buttons:["ok"],
|
||||
message:msg
|
||||
})
|
||||
});
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "新建节点",
|
||||
accelerator: "insert",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.CREATE_NODE, "unknow");
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "删除节点",
|
||||
accelerator: "delete",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.DELETE_NODE);
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "复制节点",
|
||||
accelerator: "ctrl+c",
|
||||
role: "copy",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.COPY_NODE);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "粘贴节点",
|
||||
accelerator: "ctrl+v",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.PASTE_NODE);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private createWorkspaceMenu() {
|
||||
const openWorkspace = (path: string) => {
|
||||
const curWorkspace = this.settings.curWorkspace;
|
||||
curWorkspace.setFilepath(path);
|
||||
curWorkspace.load();
|
||||
this.settings.pushRecentWorkspace(path);
|
||||
this.mainProcess.rebuildMenu();
|
||||
this.webContents.send(
|
||||
MainEventType.OPEN_DIR,
|
||||
curWorkspace.getWorkdir(),
|
||||
curWorkspace.getFilepath()
|
||||
);
|
||||
};
|
||||
const saveToNewPath = () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (!res.canceled) {
|
||||
this.settings.curWorkspace.setFilepath(res.filePath);
|
||||
this.settings.curWorkspace.save();
|
||||
openWorkspace(res.filePath);
|
||||
}
|
||||
})();
|
||||
};
|
||||
const recentItems: MenuItemConstructorOptions[] = [];
|
||||
for (let path of this.settings.recentWorkspaces) {
|
||||
recentItems.push({
|
||||
label: path,
|
||||
click: () => {
|
||||
console.log("open recent workspace", path);
|
||||
openWorkspace(path);
|
||||
},
|
||||
});
|
||||
}
|
||||
return new MenuItem({
|
||||
label: "工作区",
|
||||
submenu: [
|
||||
{
|
||||
label: "打开",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
openWorkspace(res.filePaths[0]);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "保存",
|
||||
click: () => {
|
||||
if (this.settings.curWorkspace.getFilepath()) {
|
||||
this.settings.curWorkspace.save();
|
||||
} else {
|
||||
saveToNewPath();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "另存为",
|
||||
click: () => {
|
||||
saveToNewPath();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "最近打开",
|
||||
submenu: recentItems,
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "打开目录",
|
||||
accelerator: "Ctrl+Shift+O",
|
||||
click: () => {
|
||||
if (!this.settings.curWorkspace.getNodeConfPath()) {
|
||||
dialog.showErrorBox("警告", "请先指定节点定义配置!");
|
||||
return;
|
||||
}
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openDirectory"],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const curWorkspace = this.settings.curWorkspace;
|
||||
const path = res.filePaths[0];
|
||||
curWorkspace.setWorkdir(path);
|
||||
curWorkspace.save();
|
||||
this.webContents.send(
|
||||
MainEventType.OPEN_DIR,
|
||||
path,
|
||||
curWorkspace.getFilepath()
|
||||
);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "节点定义",
|
||||
submenu: [
|
||||
{
|
||||
label: "选择文件",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const nodeConfigPath = res.filePaths[0];
|
||||
this.settings.curWorkspace.setNodeConfPath(nodeConfigPath);
|
||||
this.mainProcess.rebuildMenu();
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{ label: this.settings.nodeConfPath },
|
||||
],
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "关闭",
|
||||
click: () => {
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private createToolsMenu() {
|
||||
return new MenuItem({
|
||||
label: "开发工具",
|
||||
submenu: [
|
||||
{
|
||||
label: "打开控制台",
|
||||
accelerator: "Ctrl+Shift+I",
|
||||
click: (_, browserWindow) => {
|
||||
browserWindow.webContents.toggleDevTools();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "重载",
|
||||
accelerator: "Ctrl+R",
|
||||
click: (_, browserWindow) => {
|
||||
browserWindow.reload();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private createNodeMenu() {
|
||||
const classifyItems: MenuItemConstructorOptions[] = [];
|
||||
const map: { [key: string]: MenuItemConstructorOptions } = {};
|
||||
for (let t of this.settings.nodeClassify) {
|
||||
let item: MenuItemConstructorOptions = {
|
||||
id: t.classify,
|
||||
label: `${t.classify}(${t.desc})`,
|
||||
submenu: [],
|
||||
};
|
||||
classifyItems.push(item);
|
||||
map[t.classify] = item;
|
||||
}
|
||||
const other: MenuItemConstructorOptions = {
|
||||
id: "other",
|
||||
label: "其它",
|
||||
submenu: [],
|
||||
};
|
||||
var hasOther = false;
|
||||
|
||||
for (let node of this.settings.nodeConfig) {
|
||||
const item: MenuItemConstructorOptions = {
|
||||
label: `${node.name}(${node.desc})`,
|
||||
click: () => {
|
||||
console.log("create node", node.name);
|
||||
this.webContents.send(MainEventType.CREATE_NODE, node.name);
|
||||
},
|
||||
};
|
||||
let typeItem = map[node.type];
|
||||
if (!typeItem) {
|
||||
typeItem = other;
|
||||
hasOther = true;
|
||||
}
|
||||
if (typeItem.submenu instanceof Menu) {
|
||||
console.log("typeItem.submenu error", typeItem);
|
||||
} else {
|
||||
typeItem.submenu.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasOther) {
|
||||
classifyItems.push(other);
|
||||
}
|
||||
|
||||
return new MenuItem({
|
||||
label: "新建节点",
|
||||
submenu: classifyItems,
|
||||
});
|
||||
}
|
||||
}
|
||||
import {
|
||||
Menu,
|
||||
app,
|
||||
dialog,
|
||||
BrowserWindow,
|
||||
MenuItem,
|
||||
WebContents,
|
||||
MenuItemConstructorOptions,
|
||||
} from "electron";
|
||||
import * as fs from "fs";
|
||||
import * as Utils from "../common/Utils";
|
||||
import MainEventType from "../common/MainEventType";
|
||||
import { MainProcess } from "./MainProcess";
|
||||
import Settings from "./Settings";
|
||||
|
||||
export default class AppMenu {
|
||||
private mainProcess: MainProcess;
|
||||
private mainWindow: BrowserWindow;
|
||||
private webContents: WebContents;
|
||||
private settings: Settings;
|
||||
|
||||
constructor(mainProcess: MainProcess) {
|
||||
this.mainProcess = mainProcess;
|
||||
this.mainWindow = mainProcess.mainWindow;
|
||||
this.webContents = mainProcess.mainWindow.webContents;
|
||||
this.settings = mainProcess.settings;
|
||||
}
|
||||
|
||||
createMenu() {
|
||||
const menu: Menu = new Menu();
|
||||
menu.append(this.createWorkspaceMenu());
|
||||
menu.append(this.createFileMenu());
|
||||
menu.append(this.createNodeMenu());
|
||||
menu.append(this.createToolsMenu());
|
||||
return menu;
|
||||
}
|
||||
|
||||
private createFileMenu() {
|
||||
const fileItems: MenuItemConstructorOptions[] = [];
|
||||
for (let path of this.settings.recentFiles) {
|
||||
fileItems.push({
|
||||
label: path,
|
||||
click: () => {
|
||||
console.log("open recent file", path);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return new MenuItem({
|
||||
label: "行为树",
|
||||
submenu: [
|
||||
{
|
||||
label: "新建",
|
||||
accelerator: "ctrl+n",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (!res.canceled) {
|
||||
const path = res.filePath;
|
||||
fs.writeFileSync(
|
||||
path,
|
||||
JSON.stringify(Utils.createNewTree(path), null, 2)
|
||||
);
|
||||
this.webContents.send(MainEventType.CREATE_TREE, path);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "打开文件",
|
||||
accelerator: "Ctrl+O",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const path = res.filePaths[0];
|
||||
if (this.settings.recentFiles.indexOf(path) < 0) {
|
||||
this.settings.recentFiles.unshift(path);
|
||||
this.settings.save();
|
||||
this.mainProcess.rebuildMenu();
|
||||
}
|
||||
this.webContents.send(MainEventType.OPEN_FILE, path);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "最近打开",
|
||||
submenu: fileItems,
|
||||
},
|
||||
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "保存",
|
||||
accelerator: "ctrl+s",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.SAVE);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "全部保存",
|
||||
accelerator: "ctrl+shift+s",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.SAVE_ALL);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "合并导出Json",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePath) {
|
||||
const curWorkspace = this.settings.curWorkspace;
|
||||
curWorkspace.writeAllTrees(res.filePath, (err) => {
|
||||
const msg = err ? err : "导出成功";
|
||||
dialog.showMessageBox({
|
||||
type: "info",
|
||||
buttons: ["ok"],
|
||||
message: msg,
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "新建节点",
|
||||
accelerator: "insert",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.CREATE_NODE, "unknow");
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "删除节点",
|
||||
accelerator: "delete",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.DELETE_NODE);
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "复制节点",
|
||||
accelerator: "ctrl+c",
|
||||
role: "copy",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.COPY_NODE);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "粘贴节点",
|
||||
accelerator: "ctrl+v",
|
||||
click: () => {
|
||||
this.webContents.send(MainEventType.PASTE_NODE);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private createWorkspaceMenu() {
|
||||
const openWorkspace = (path: string) => {
|
||||
const curWorkspace = this.settings.curWorkspace;
|
||||
curWorkspace.setFilepath(path);
|
||||
curWorkspace.load();
|
||||
this.settings.pushRecentWorkspace(path);
|
||||
this.mainProcess.rebuildMenu();
|
||||
this.webContents.send(
|
||||
MainEventType.OPEN_DIR,
|
||||
curWorkspace.getWorkdir(),
|
||||
curWorkspace.getFilepath()
|
||||
);
|
||||
};
|
||||
const saveToNewPath = () => {
|
||||
(async () => {
|
||||
const res = await dialog.showSaveDialog({
|
||||
properties: ["showOverwriteConfirmation"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (!res.canceled) {
|
||||
this.settings.curWorkspace.setFilepath(res.filePath);
|
||||
this.settings.curWorkspace.save();
|
||||
openWorkspace(res.filePath);
|
||||
}
|
||||
})();
|
||||
};
|
||||
const recentItems: MenuItemConstructorOptions[] = [];
|
||||
for (let path of this.settings.recentWorkspaces) {
|
||||
recentItems.push({
|
||||
label: path,
|
||||
click: () => {
|
||||
console.log("open recent workspace", path);
|
||||
openWorkspace(path);
|
||||
},
|
||||
});
|
||||
}
|
||||
return new MenuItem({
|
||||
label: "工作区",
|
||||
submenu: [
|
||||
{
|
||||
label: "打开",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
openWorkspace(res.filePaths[0]);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "保存",
|
||||
click: () => {
|
||||
if (this.settings.curWorkspace.getFilepath()) {
|
||||
this.settings.curWorkspace.save();
|
||||
} else {
|
||||
saveToNewPath();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "另存为",
|
||||
click: () => {
|
||||
saveToNewPath();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "最近打开",
|
||||
submenu: recentItems,
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "打开目录",
|
||||
accelerator: "Ctrl+Shift+O",
|
||||
click: () => {
|
||||
if (!this.settings.curWorkspace.getNodeConfPath()) {
|
||||
dialog.showErrorBox("警告", "请先指定节点定义配置!");
|
||||
return;
|
||||
}
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openDirectory"],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const curWorkspace = this.settings.curWorkspace;
|
||||
const path = res.filePaths[0];
|
||||
curWorkspace.setWorkdir(path);
|
||||
curWorkspace.save();
|
||||
this.webContents.send(
|
||||
MainEventType.OPEN_DIR,
|
||||
path,
|
||||
curWorkspace.getFilepath()
|
||||
);
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "节点定义",
|
||||
submenu: [
|
||||
{
|
||||
label: "选择文件",
|
||||
click: () => {
|
||||
(async () => {
|
||||
const res = await dialog.showOpenDialog({
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Json", extensions: ["json"] }],
|
||||
});
|
||||
if (res.filePaths.length > 0) {
|
||||
const nodeConfigPath = res.filePaths[0];
|
||||
this.settings.curWorkspace.setNodeConfPath(nodeConfigPath);
|
||||
this.mainProcess.rebuildMenu();
|
||||
}
|
||||
})();
|
||||
},
|
||||
},
|
||||
{ type: "separator" },
|
||||
{ label: this.settings.nodeConfPath },
|
||||
],
|
||||
},
|
||||
{ type: "separator" },
|
||||
{
|
||||
label: "关闭",
|
||||
click: () => {
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private createToolsMenu() {
|
||||
return new MenuItem({
|
||||
label: "开发工具",
|
||||
submenu: [
|
||||
{
|
||||
label: "打开控制台",
|
||||
accelerator: "Ctrl+Shift+I",
|
||||
click: (_, browserWindow) => {
|
||||
browserWindow.webContents.toggleDevTools();
|
||||
},
|
||||
},
|
||||
{
|
||||
label: "重载",
|
||||
accelerator: "Ctrl+R",
|
||||
click: (_, browserWindow) => {
|
||||
browserWindow.reload();
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
private createNodeMenu() {
|
||||
const classifyItems: MenuItemConstructorOptions[] = [];
|
||||
const map: { [key: string]: MenuItemConstructorOptions } = {};
|
||||
for (let t of this.settings.nodeClassify) {
|
||||
let item: MenuItemConstructorOptions = {
|
||||
id: t.classify,
|
||||
label: `${t.classify}(${t.desc})`,
|
||||
submenu: [],
|
||||
};
|
||||
classifyItems.push(item);
|
||||
map[t.classify] = item;
|
||||
}
|
||||
const other: MenuItemConstructorOptions = {
|
||||
id: "other",
|
||||
label: "其它",
|
||||
submenu: [],
|
||||
};
|
||||
var hasOther = false;
|
||||
|
||||
for (let node of this.settings.nodeConfig) {
|
||||
const item: MenuItemConstructorOptions = {
|
||||
label: `${node.name}(${node.desc})`,
|
||||
click: () => {
|
||||
console.log("create node", node.name);
|
||||
this.webContents.send(MainEventType.CREATE_NODE, node.name);
|
||||
},
|
||||
};
|
||||
let typeItem = map[node.type];
|
||||
if (!typeItem) {
|
||||
typeItem = other;
|
||||
hasOther = true;
|
||||
}
|
||||
if (typeItem.submenu instanceof Menu) {
|
||||
console.log("typeItem.submenu error", typeItem);
|
||||
} else {
|
||||
typeItem.submenu.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasOther) {
|
||||
classifyItems.push(other);
|
||||
}
|
||||
|
||||
return new MenuItem({
|
||||
label: "新建节点",
|
||||
submenu: classifyItems,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,72 +1,70 @@
|
||||
import { app, BrowserWindow, Menu, MenuItem, dialog, nativeTheme } from 'electron';
|
||||
import AppMenu from './AppMenu'
|
||||
import Settings from './Settings';
|
||||
import MainEventType from '../common/MainEventType';
|
||||
|
||||
const electronLocalshortcut = require('electron-localshortcut');
|
||||
|
||||
// 一些暴露给render-process的全局变量
|
||||
export interface Global {
|
||||
settings: Settings
|
||||
}
|
||||
declare var global: Global;
|
||||
|
||||
export class MainProcess {
|
||||
mainWindow: BrowserWindow;
|
||||
appMenu: AppMenu;
|
||||
settings: Settings;
|
||||
constructor() {
|
||||
nativeTheme.themeSource = 'dark';
|
||||
app.on('ready', () => {
|
||||
this.createWindow();
|
||||
electronLocalshortcut.register(this.mainWindow, 'Ctrl+C', () => {
|
||||
this.mainWindow.webContents.send(MainEventType.COPY_NODE);
|
||||
});
|
||||
electronLocalshortcut.register(this.mainWindow, 'Ctrl+V', () => {
|
||||
this.mainWindow.webContents.send(MainEventType.PASTE_NODE);
|
||||
});
|
||||
})
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
app.on('activate', () => {
|
||||
if (this.mainWindow === null) {
|
||||
this.createWindow()
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
createWindow() {
|
||||
this.settings = new Settings();
|
||||
global.settings = this.settings;
|
||||
|
||||
this.mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
enableRemoteModule: true,
|
||||
}
|
||||
// fullscreenable:false,
|
||||
// maximizable:false
|
||||
});
|
||||
this.mainWindow.maximize();
|
||||
// mainWindow.webContents.openDevTools();
|
||||
this.mainWindow.loadFile('index.html');
|
||||
this.mainWindow.on('closed', function () {
|
||||
this.mainWindow = null
|
||||
});
|
||||
this.appMenu = new AppMenu(this);
|
||||
this.rebuildMenu();
|
||||
}
|
||||
|
||||
rebuildMenu() {
|
||||
Menu.setApplicationMenu(this.appMenu.createMenu());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default new MainProcess();
|
||||
|
||||
import { app, BrowserWindow, Menu, MenuItem, dialog, nativeTheme } from "electron";
|
||||
import AppMenu from "./AppMenu";
|
||||
import Settings from "./Settings";
|
||||
import MainEventType from "../common/MainEventType";
|
||||
|
||||
const electronLocalshortcut = require("electron-localshortcut");
|
||||
|
||||
// 一些暴露给render-process的全局变量
|
||||
export interface Global {
|
||||
settings: Settings;
|
||||
}
|
||||
declare var global: Global;
|
||||
|
||||
export class MainProcess {
|
||||
mainWindow: BrowserWindow;
|
||||
appMenu: AppMenu;
|
||||
settings: Settings;
|
||||
constructor() {
|
||||
nativeTheme.themeSource = "dark";
|
||||
app.on("ready", () => {
|
||||
this.createWindow();
|
||||
electronLocalshortcut.register(this.mainWindow, "Ctrl+C", () => {
|
||||
this.mainWindow.webContents.send(MainEventType.COPY_NODE);
|
||||
});
|
||||
electronLocalshortcut.register(this.mainWindow, "Ctrl+V", () => {
|
||||
this.mainWindow.webContents.send(MainEventType.PASTE_NODE);
|
||||
});
|
||||
});
|
||||
app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
app.on("activate", () => {
|
||||
if (this.mainWindow === null) {
|
||||
this.createWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
createWindow() {
|
||||
this.settings = new Settings();
|
||||
global.settings = this.settings;
|
||||
|
||||
this.mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
enableRemoteModule: true,
|
||||
},
|
||||
// fullscreenable:false,
|
||||
// maximizable:false
|
||||
});
|
||||
this.mainWindow.maximize();
|
||||
// mainWindow.webContents.openDevTools();
|
||||
this.mainWindow.loadFile("index.html");
|
||||
this.mainWindow.on("closed", function () {
|
||||
this.mainWindow = null;
|
||||
});
|
||||
this.appMenu = new AppMenu(this);
|
||||
this.rebuildMenu();
|
||||
}
|
||||
|
||||
rebuildMenu() {
|
||||
Menu.setApplicationMenu(this.appMenu.createMenu());
|
||||
}
|
||||
}
|
||||
|
||||
export default new MainProcess();
|
||||
+89
-90
@@ -1,90 +1,89 @@
|
||||
import * as fs from 'fs';
|
||||
import { BehaviorNodeTypeModel } from '../common/BehaviorTreeModel';
|
||||
import Workspace from './Workspace';
|
||||
|
||||
export interface BehaviorNodeClassify {
|
||||
classify: string;
|
||||
desc?: string;
|
||||
}
|
||||
|
||||
export interface SettingsModel {
|
||||
recentWorkspaces?: string[];
|
||||
recentFiles?: string[];
|
||||
nodeClassify?: BehaviorNodeClassify[];
|
||||
}
|
||||
|
||||
const settingPath = 'settings.json';
|
||||
const sampleNodeClassify: BehaviorNodeClassify[] = [
|
||||
{ classify: "Composite", desc: "复合节点" },
|
||||
{ classify: "Decorator", desc: "修饰节点" },
|
||||
{ classify: "Condition", desc: "条件节点" },
|
||||
{ classify: "Action", desc: "行为节点" },
|
||||
]
|
||||
|
||||
|
||||
export default class Settings {
|
||||
private settings: SettingsModel;
|
||||
curWorkspace?: Workspace;
|
||||
|
||||
constructor() {
|
||||
this.load();
|
||||
}
|
||||
|
||||
get nodeConfPath() {
|
||||
return this.curWorkspace.getNodeConfPath();
|
||||
}
|
||||
get recentWorkspaces() {
|
||||
return this.settings.recentWorkspaces;
|
||||
}
|
||||
get recentFiles() {
|
||||
return this.settings.recentFiles;
|
||||
}
|
||||
get nodeConfig() {
|
||||
return this.curWorkspace.nodeConf;
|
||||
}
|
||||
get nodeClassify() {
|
||||
return this.settings.nodeClassify;
|
||||
}
|
||||
|
||||
set(config: SettingsModel) {
|
||||
this.settings = {
|
||||
...this.settings,
|
||||
...config
|
||||
};
|
||||
this.save();
|
||||
}
|
||||
|
||||
load() {
|
||||
if (fs.existsSync(settingPath)) {
|
||||
const str = fs.readFileSync(settingPath, 'utf8');
|
||||
this.settings = JSON.parse(str);
|
||||
} else {
|
||||
this.settings = {
|
||||
recentWorkspaces: ['sample/workspace.json'],
|
||||
recentFiles: [],
|
||||
nodeClassify: sampleNodeClassify,
|
||||
};
|
||||
this.save();
|
||||
}
|
||||
this.curWorkspace = new Workspace(this.settings.recentWorkspaces[0]);
|
||||
this.curWorkspace.load();
|
||||
}
|
||||
|
||||
save() {
|
||||
fs.writeFileSync(settingPath, JSON.stringify(this.settings, null, 2));
|
||||
}
|
||||
|
||||
getNodeConf(name: string) {
|
||||
return this.curWorkspace.getNodeConf(name);
|
||||
}
|
||||
|
||||
pushRecentWorkspace(path: string) {
|
||||
if (this.settings.recentWorkspaces.indexOf(path) < 0) {
|
||||
this.settings.recentWorkspaces.unshift(path);
|
||||
console.log("push", path);
|
||||
} else {
|
||||
console.log("already in path", this.settings.recentWorkspaces, path);
|
||||
}
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
import * as fs from "fs";
|
||||
import { BehaviorNodeTypeModel } from "../common/BehaviorTreeModel";
|
||||
import Workspace from "./Workspace";
|
||||
|
||||
export interface BehaviorNodeClassify {
|
||||
classify: string;
|
||||
desc?: string;
|
||||
}
|
||||
|
||||
export interface SettingsModel {
|
||||
recentWorkspaces?: string[];
|
||||
recentFiles?: string[];
|
||||
nodeClassify?: BehaviorNodeClassify[];
|
||||
}
|
||||
|
||||
const settingPath = "settings.json";
|
||||
const sampleNodeClassify: BehaviorNodeClassify[] = [
|
||||
{ classify: "Composite", desc: "复合节点" },
|
||||
{ classify: "Decorator", desc: "修饰节点" },
|
||||
{ classify: "Condition", desc: "条件节点" },
|
||||
{ classify: "Action", desc: "行为节点" },
|
||||
];
|
||||
|
||||
export default class Settings {
|
||||
private settings: SettingsModel;
|
||||
curWorkspace?: Workspace;
|
||||
|
||||
constructor() {
|
||||
this.load();
|
||||
}
|
||||
|
||||
get nodeConfPath() {
|
||||
return this.curWorkspace.getNodeConfPath();
|
||||
}
|
||||
get recentWorkspaces() {
|
||||
return this.settings.recentWorkspaces;
|
||||
}
|
||||
get recentFiles() {
|
||||
return this.settings.recentFiles;
|
||||
}
|
||||
get nodeConfig() {
|
||||
return this.curWorkspace.nodeConf;
|
||||
}
|
||||
get nodeClassify() {
|
||||
return this.settings.nodeClassify;
|
||||
}
|
||||
|
||||
set(config: SettingsModel) {
|
||||
this.settings = {
|
||||
...this.settings,
|
||||
...config,
|
||||
};
|
||||
this.save();
|
||||
}
|
||||
|
||||
load() {
|
||||
if (fs.existsSync(settingPath)) {
|
||||
const str = fs.readFileSync(settingPath, "utf8");
|
||||
this.settings = JSON.parse(str);
|
||||
} else {
|
||||
this.settings = {
|
||||
recentWorkspaces: ["sample/workspace.json"],
|
||||
recentFiles: [],
|
||||
nodeClassify: sampleNodeClassify,
|
||||
};
|
||||
this.save();
|
||||
}
|
||||
this.curWorkspace = new Workspace(this.settings.recentWorkspaces[0]);
|
||||
this.curWorkspace.load();
|
||||
}
|
||||
|
||||
save() {
|
||||
fs.writeFileSync(settingPath, JSON.stringify(this.settings, null, 2));
|
||||
}
|
||||
|
||||
getNodeConf(name: string) {
|
||||
return this.curWorkspace.getNodeConf(name);
|
||||
}
|
||||
|
||||
pushRecentWorkspace(path: string) {
|
||||
if (this.settings.recentWorkspaces.indexOf(path) < 0) {
|
||||
this.settings.recentWorkspaces.unshift(path);
|
||||
console.log("push", path);
|
||||
} else {
|
||||
console.log("already in path", this.settings.recentWorkspaces, path);
|
||||
}
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
+139
-137
@@ -1,137 +1,139 @@
|
||||
import * as fs from "fs";
|
||||
import { BehaviorNodeTypeModel } from "../common/BehaviorTreeModel";
|
||||
import * as glob from "glob";
|
||||
import * as path from "path";
|
||||
|
||||
export interface WorkspaceModel {
|
||||
isRelative?: boolean;
|
||||
nodeConfPath: string;
|
||||
workdir: string;
|
||||
}
|
||||
|
||||
const unknowNodeType: BehaviorNodeTypeModel = {
|
||||
name: "unknow",
|
||||
desc: "新建节点",
|
||||
type: "Action",
|
||||
};
|
||||
|
||||
export default class Workspace {
|
||||
private filepath: string;
|
||||
private nodeConfPath: string;
|
||||
private workdir: string;
|
||||
|
||||
private name2conf: { [name: string]: BehaviorNodeTypeModel } = {};
|
||||
private types: BehaviorNodeTypeModel[] = [];
|
||||
|
||||
constructor(filepath: string) {
|
||||
this.filepath = filepath;
|
||||
}
|
||||
|
||||
load() {
|
||||
if (!this.filepath) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const str = fs.readFileSync(this.filepath, 'utf8');
|
||||
const model = JSON.parse(str) as WorkspaceModel;
|
||||
if (model.isRelative) {
|
||||
const root = path.dirname(this.filepath);
|
||||
this.nodeConfPath = root + '/' + model.nodeConfPath;
|
||||
this.workdir = root + '/' + model.workdir;
|
||||
} else {
|
||||
this.nodeConfPath = model.nodeConfPath;
|
||||
this.workdir = model.workdir;
|
||||
}
|
||||
|
||||
this.initNodeConf();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
private initNodeConf() {
|
||||
if (!this.nodeConfPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const types: BehaviorNodeTypeModel[] = JSON.parse(fs.readFileSync(this.nodeConfPath, 'utf8'));
|
||||
this.name2conf = {};
|
||||
types.forEach(t => {
|
||||
this.name2conf[t.name] = t;
|
||||
})
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
getNodeConfPath() {
|
||||
return this.nodeConfPath;
|
||||
}
|
||||
setNodeConfPath(path: string) {
|
||||
this.nodeConfPath = path;
|
||||
this.initNodeConf();
|
||||
}
|
||||
getWorkdir(): string {
|
||||
return this.workdir;
|
||||
}
|
||||
setWorkdir(workdir: string) {
|
||||
this.workdir = workdir;
|
||||
}
|
||||
|
||||
writeAllTrees(outFilePath: string, cb?: (err: string) => void) {
|
||||
if (!fs.existsSync(this.getWorkdir())) {
|
||||
cb && cb("请先打开工作区");
|
||||
return;
|
||||
}
|
||||
glob.glob(path.join(this.getWorkdir(), "**/*.json"), function (err, files) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
cb && cb(err.message);
|
||||
return;
|
||||
}
|
||||
|
||||
let result = new Array();
|
||||
files.forEach((file) => {
|
||||
const data = fs.readFileSync(file, "utf8");
|
||||
result.push(JSON.parse(data));
|
||||
});
|
||||
|
||||
fs.writeFileSync(outFilePath, JSON.stringify(result, null, 2));
|
||||
cb && cb(null);
|
||||
});
|
||||
}
|
||||
|
||||
save(filepath?: string) {
|
||||
if (filepath) {
|
||||
this.filepath = filepath;
|
||||
}
|
||||
if (!this.filepath) {
|
||||
return;
|
||||
}
|
||||
fs.writeFileSync(
|
||||
this.filepath,
|
||||
JSON.stringify(
|
||||
{
|
||||
nodeConfPath: this.nodeConfPath,
|
||||
workdir: this.workdir,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
get nodeConf() {
|
||||
return this.types;
|
||||
}
|
||||
|
||||
getFilepath() {
|
||||
return this.filepath;
|
||||
}
|
||||
|
||||
setFilepath(filepath: string) {
|
||||
this.filepath = filepath;
|
||||
}
|
||||
|
||||
getNodeConf(name: string) {
|
||||
return this.name2conf[name] || unknowNodeType;
|
||||
}
|
||||
}
|
||||
import * as fs from "fs";
|
||||
import { BehaviorNodeTypeModel } from "../common/BehaviorTreeModel";
|
||||
import * as glob from "glob";
|
||||
import * as path from "path";
|
||||
|
||||
export interface WorkspaceModel {
|
||||
isRelative?: boolean;
|
||||
nodeConfPath: string;
|
||||
workdir: string;
|
||||
}
|
||||
|
||||
const unknowNodeType: BehaviorNodeTypeModel = {
|
||||
name: "unknow",
|
||||
desc: "新建节点",
|
||||
type: "Action",
|
||||
};
|
||||
|
||||
export default class Workspace {
|
||||
private filepath: string;
|
||||
private nodeConfPath: string;
|
||||
private workdir: string;
|
||||
|
||||
private name2conf: { [name: string]: BehaviorNodeTypeModel } = {};
|
||||
private types: BehaviorNodeTypeModel[] = [];
|
||||
|
||||
constructor(filepath: string) {
|
||||
this.filepath = filepath;
|
||||
}
|
||||
|
||||
load() {
|
||||
if (!this.filepath) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const str = fs.readFileSync(this.filepath, "utf8");
|
||||
const model = JSON.parse(str) as WorkspaceModel;
|
||||
if (model.isRelative) {
|
||||
const root = path.dirname(this.filepath);
|
||||
this.nodeConfPath = root + "/" + model.nodeConfPath;
|
||||
this.workdir = root + "/" + model.workdir;
|
||||
} else {
|
||||
this.nodeConfPath = model.nodeConfPath;
|
||||
this.workdir = model.workdir;
|
||||
}
|
||||
|
||||
this.initNodeConf();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
private initNodeConf() {
|
||||
if (!this.nodeConfPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const types: BehaviorNodeTypeModel[] = JSON.parse(
|
||||
fs.readFileSync(this.nodeConfPath, "utf8")
|
||||
);
|
||||
this.name2conf = {};
|
||||
types.forEach((t) => {
|
||||
this.name2conf[t.name] = t;
|
||||
});
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
getNodeConfPath() {
|
||||
return this.nodeConfPath;
|
||||
}
|
||||
setNodeConfPath(path: string) {
|
||||
this.nodeConfPath = path;
|
||||
this.initNodeConf();
|
||||
}
|
||||
getWorkdir(): string {
|
||||
return this.workdir;
|
||||
}
|
||||
setWorkdir(workdir: string) {
|
||||
this.workdir = workdir;
|
||||
}
|
||||
|
||||
writeAllTrees(outFilePath: string, cb?: (err: string) => void) {
|
||||
if (!fs.existsSync(this.getWorkdir())) {
|
||||
cb && cb("请先打开工作区");
|
||||
return;
|
||||
}
|
||||
glob.glob(path.join(this.getWorkdir(), "**/*.json"), function (err, files) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
cb && cb(err.message);
|
||||
return;
|
||||
}
|
||||
|
||||
let result = new Array();
|
||||
files.forEach((file) => {
|
||||
const data = fs.readFileSync(file, "utf8");
|
||||
result.push(JSON.parse(data));
|
||||
});
|
||||
|
||||
fs.writeFileSync(outFilePath, JSON.stringify(result, null, 2));
|
||||
cb && cb(null);
|
||||
});
|
||||
}
|
||||
|
||||
save(filepath?: string) {
|
||||
if (filepath) {
|
||||
this.filepath = filepath;
|
||||
}
|
||||
if (!this.filepath) {
|
||||
return;
|
||||
}
|
||||
fs.writeFileSync(
|
||||
this.filepath,
|
||||
JSON.stringify(
|
||||
{
|
||||
nodeConfPath: this.nodeConfPath,
|
||||
workdir: this.workdir,
|
||||
},
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
get nodeConf() {
|
||||
return this.types;
|
||||
}
|
||||
|
||||
getFilepath() {
|
||||
return this.filepath;
|
||||
}
|
||||
|
||||
setFilepath(filepath: string) {
|
||||
this.filepath = filepath;
|
||||
}
|
||||
|
||||
getNodeConf(name: string) {
|
||||
return this.name2conf[name] || unknowNodeType;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user