add Workspace

This commit is contained in:
zhandouxiaojiji committed 2020-11-04 20:16:14 +08:00
1 parent c4eb53ac68
commit 70cc4dca87
6 files changed
+215 -78

No files matched your search

+1
View File
@@ -1,5 +1,6 @@
export default { export default {
OPEN_FILE: "OPEN_FILE", OPEN_FILE: "OPEN_FILE",
OPEN_DIR: "OPEN_DIR",
OPEN_WORKSPACE: "OPEN_WORKSPACE", OPEN_WORKSPACE: "OPEN_WORKSPACE",
CREATE_NODE: 'CREATE_NODE', CREATE_NODE: 'CREATE_NODE',
SAVE: 'SAVE', SAVE: 'SAVE',
+95 -45
View File
@@ -18,9 +18,9 @@ export default class AppMenu {
createMenu() { createMenu() {
const menu: Menu = new Menu(); const menu: Menu = new Menu();
menu.append(this.createWorkspaceMenu());
menu.append(this.createFileMenu()); menu.append(this.createFileMenu());
menu.append(this.createNodeMenu()); menu.append(this.createNodeMenu());
menu.append(this.createSettingsMenu());
menu.append(this.createToolsMenu()); menu.append(this.createToolsMenu());
return menu; return menu;
} }
@@ -35,15 +35,7 @@ export default class AppMenu {
} }
}) })
} }
const workspaceItems: MenuItemConstructorOptions[] = [];
for (let path of this.settings.recentWorkspaces) {
workspaceItems.push({
label: path,
click: () => {
console.log("open recent workspace", path);
}
})
}
return new MenuItem({ return new MenuItem({
label: "行为树", label: "行为树",
@@ -71,35 +63,12 @@ export default class AppMenu {
})(); })();
} }
}, },
{
label: "打开目录",
accelerator: "Ctrl+Shift+O",
click: () => {
(async () => {
const res = await dialog.showOpenDialog({
properties: ['openDirectory']
});
if (res.filePaths.length > 0) {
const path = res.filePaths[0];
if (this.settings.recentWorkspaces.indexOf(path) < 0) {
this.settings.recentWorkspaces.unshift(path);
this.settings.save();
this.mainProcess.rebuildMenu();
}
this.webContents.send(MainEventType.OPEN_WORKSPACE, path);
}
})();
}
},
{ type: 'separator' }, { type: 'separator' },
{ {
label: "最近打开", label: "最近打开",
submenu: fileItems, submenu: fileItems,
}, },
{
label: "最近目录",
submenu: workspaceItems,
},
{ type: 'separator' }, { type: 'separator' },
{ {
label: "保存", label: "保存",
@@ -113,21 +82,95 @@ export default class AppMenu {
this.webContents.send(MainEventType.SAVE_ALL); this.webContents.send(MainEventType.SAVE_ALL);
}, },
}, },
{ type: 'separator' },
{
label: "关闭",
click: () => {
app.quit();
}
}
] ]
}); });
} }
private createSettingsMenu() { private createWorkspaceMenu() {
const openWorkspace = (path: string) => {
this.settings.curWorkspace.setFilepath(path);
this.settings.curWorkspace.load();
this.settings.pushRecentWorkspace(path);
this.mainProcess.rebuildMenu();
this.webContents.send(MainEventType.OPEN_DIR, this.settings.curWorkspace.getWorkdir());
};
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({ return new MenuItem({
label: "设置", label: "工作区",
submenu: [ 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 {
(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();
}
})();
}
}
},
{
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 path = res.filePaths[0];
this.settings.curWorkspace.setWorkdir(path);
this.settings.curWorkspace.save();
this.webContents.send(MainEventType.OPEN_DIR, path);
}
})();
}
},
{ {
label: "节点定义", label: "节点定义",
submenu: [ submenu: [
@@ -143,15 +186,22 @@ export default class AppMenu {
}); });
if (res.filePaths.length > 0) { if (res.filePaths.length > 0) {
const nodeConfigPath = res.filePaths[0]; const nodeConfigPath = res.filePaths[0];
this.settings.set({ nodeConfigPath }); this.settings.curWorkspace.setNodeConfPath(nodeConfigPath);
this.mainProcess.rebuildMenu(); this.mainProcess.rebuildMenu();
} }
})(); })();
} }
}, },
{ type: 'separator' }, { type: 'separator' },
{ label: this.settings.nodeConfigPath, } { label: this.settings.nodeConfPath, }
] ]
},
{ type: 'separator' },
{
label: "关闭",
click: () => {
app.quit();
}
} }
] ]
}); });
+17 -18
View File
@@ -1,5 +1,6 @@
import * as fs from 'fs'; import * as fs from 'fs';
import { BehaviorNodeTypeModel } from '../common/BehaviorTreeModel'; import { BehaviorNodeTypeModel } from '../common/BehaviorTreeModel';
import Workspace from './Workspace';
export interface BehaviorNodeClassify { export interface BehaviorNodeClassify {
classify: string; classify: string;
@@ -9,7 +10,6 @@ export interface BehaviorNodeClassify {
export interface SettingsModel { export interface SettingsModel {
recentWorkspaces?: string[]; recentWorkspaces?: string[];
recentFiles?: string[]; recentFiles?: string[];
nodeConfigPath?: string; // 节点配置路径
nodeClassify?: BehaviorNodeClassify[]; nodeClassify?: BehaviorNodeClassify[];
} }
@@ -22,21 +22,18 @@ const sampleNodeClassify: BehaviorNodeClassify[] = [
{ classify: "Action", desc: "行为节点" }, { classify: "Action", desc: "行为节点" },
] ]
const unknowNodeType: BehaviorNodeTypeModel = {
name: 'unknow',
desc: '新建节点',
type: 'Action',
}
export default class Settings { export default class Settings {
private settings: SettingsModel; private settings: SettingsModel;
private name2conf: { [name: string]: BehaviorNodeTypeModel } = {}; curWorkspace?: Workspace;
constructor() { constructor() {
this.load(); this.load();
} }
get nodeConfigPath() { get nodeConfPath() {
return this.settings.nodeConfigPath; return this.curWorkspace.getNodeConfPath();
} }
get recentWorkspaces() { get recentWorkspaces() {
return this.settings.recentWorkspaces; return this.settings.recentWorkspaces;
@@ -45,13 +42,7 @@ export default class Settings {
return this.settings.recentFiles; return this.settings.recentFiles;
} }
get nodeConfig() { get nodeConfig() {
const str = fs.readFileSync(this.nodeConfigPath, 'utf8'); return this.curWorkspace.nodeConf;
const types: BehaviorNodeTypeModel[] = JSON.parse(str);
this.name2conf = {};
types.forEach(t => {
this.name2conf[t.name] = t;
})
return types;
} }
get nodeClassify() { get nodeClassify() {
return this.settings.nodeClassify; return this.settings.nodeClassify;
@@ -73,11 +64,12 @@ export default class Settings {
this.settings = { this.settings = {
recentWorkspaces: [], recentWorkspaces: [],
recentFiles: [], recentFiles: [],
nodeConfigPath: sampleNodeConfig,
nodeClassify: sampleNodeClassify, nodeClassify: sampleNodeClassify,
}; };
this.save(); this.save();
} }
this.curWorkspace = new Workspace(this.settings.recentWorkspaces[0]);
this.curWorkspace.load();
} }
save() { save() {
@@ -85,6 +77,13 @@ export default class Settings {
} }
getNodeConf(name: string) { getNodeConf(name: string) {
return this.name2conf[name] || unknowNodeType; return this.curWorkspace.getNodeConf(name);
}
pushRecentWorkspace(path: string) {
if (this.settings.recentWorkspaces.indexOf(path) < 0) {
this.settings.recentWorkspaces.unshift(path);
}
this.save();
} }
} }
+90
View File
@@ -0,0 +1,90 @@
import * as fs from 'fs';
import { BehaviorNodeTypeModel } from '../common/BehaviorTreeModel';
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;
}
const str = fs.readFileSync(this.filepath, 'utf8');
const data = JSON.parse(str);
this.nodeConfPath = data.nodeConfPath;
this.workdir = data.workdir;
this.initNodeConf();
}
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() {
return this.workdir;
}
setWorkdir(workdir: string) {
this.workdir = workdir;
}
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;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "behavior3editor", "name": "behavior3editor",
"version": "0.0.3", "version": "0.1.0",
"description": "行为树编辑器", "description": "行为树编辑器",
"main": "./dist/main.js", "main": "./dist/main.js",
"scripts": { "scripts": {
+11 -14
View File
@@ -23,12 +23,12 @@ const { TabPane } = Tabs;
interface MainState { interface MainState {
workspace: string; workdir: string;
} }
export default class Main extends Component { export default class Main extends Component {
state: MainState = { state: MainState = {
workspace: '', workdir: '',
} }
settings: Settings; settings: Settings;
@@ -44,17 +44,14 @@ export default class Main extends Component {
this.setState({ curPath: path }); this.setState({ curPath: path });
}); });
ipcRenderer.on(MainEventType.OPEN_WORKSPACE, (event: any, workspace: any) => { ipcRenderer.on(MainEventType.OPEN_DIR, (event: any, workdir: any) => {
console.log("on open workspace", workspace); console.log("on open workspace", workdir);
document.title = workspace; document.title = workdir;
this.setState({ workspace }); this.setState({ workdir });
}); });
this.setState({ workspace: this.getLastWorkspace() }); console.log("workdir", this.settings.curWorkspace.getWorkdir());
} this.setState({ workdir: this.settings.curWorkspace.getWorkdir() });
getLastWorkspace() {
return this.settings.recentWorkspaces[0];
} }
updateSettings() { updateSettings() {
@@ -63,13 +60,13 @@ export default class Main extends Component {
render() { render() {
console.log("render main"); console.log("render main");
const { workspace } = this.state; const { workdir } = this.state;
document.title = `行为树编辑器 - ${workspace}`; document.title = `行为树编辑器 - ${workdir}`;
return ( return (
<Layout className="body"> <Layout className="body">
<Sider className="sider" width={250}> <Sider className="sider" width={250}>
<Properties <Properties
workspace={this.state.workspace} workspace={this.state.workdir}
onOpenTree={(path) => { onOpenTree={(path) => {
this.tabs.openFile(path); this.tabs.openFile(path);
}} }}