undo & redo

This commit is contained in:
zhandouxiaojiji committed 2020-12-01 21:15:08 +08:00
1 parent 8c6991afb3
commit d87cba3622
6 files changed
+76 -10

No files matched your search

-2
View File
@@ -53,8 +53,6 @@ npm run dist # 编译exe可执行文件
+ js/ts版本 计划中。
## TODO
+ 历史记录(撤销/恢复)
+ 资源面板支持树型结构
+ 右键菜单
## About
+2
View File
@@ -10,4 +10,6 @@ export default {
SAVE: "SAVE",
SAVE_ALL: "SAVE_ALL",
RELOAD_SERVER: "RELOAD_SERVER",
UNDO: "UNDO",
REDO: "REDO",
};
+26 -3
View File
@@ -28,9 +28,10 @@ export default class AppMenu {
createMenu() {
const menu: Menu = new Menu();
menu.append(this.createWorkspaceMenu());
menu.append(this.createFileMenu());
menu.append(this.createEditMenu());
menu.append(this.createNodeMenu());
menu.append(this.createWorkspaceMenu());
menu.append(this.createToolsMenu());
return menu;
}
@@ -133,6 +134,28 @@ export default class AppMenu {
})();
},
},
],
});
}
private createEditMenu() {
return new MenuItem({
label: "编辑",
submenu: [
{
label: "撤销",
accelerator: "ctrl+z",
click: () => {
this.webContents.send(MainEventType.UNDO);
}
},
{
label: "恢复",
accelerator: "ctrl+y",
click: () => {
this.webContents.send(MainEventType.REDO);
}
},
{ type: "separator" },
{
label: "新建节点",
@@ -164,8 +187,8 @@ export default class AppMenu {
this.webContents.send(MainEventType.PASTE_NODE);
},
},
],
});
]
})
}
private createWorkspaceMenu() {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "behavior3editor",
"version": "0.1.3",
"version": "0.1.4",
"description": "行为树编辑器",
"main": "./dist/main.js",
"scripts": {
+37 -4
View File
@@ -16,6 +16,7 @@ import Settings from "../../main-process/Settings";
import "./Editor.css";
import { clipboard } from "electron";
import { TreeGraphData } from "@antv/g6/lib/types";
export interface EditorProps {
filepath: string;
@@ -35,6 +36,8 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
private dragSrcId: string;
private dragDstId: string;
private autoId: number;
private undoStack: BehaviorNodeModel[] = [];
private redoStack: BehaviorNodeModel[] = [];
constructor(props: EditorProps) {
super(props);
@@ -219,6 +222,7 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
}
const removeSrc = () => {
this.pushUndoStack();
srcParent.children = srcParent.children.filter((e) => e.id != srcData.id);
};
console.log("dstNode", dstNode);
@@ -286,6 +290,7 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
message.warn("未选中节点");
return;
}
this.pushUndoStack();
const curNodeData = this.graph.findDataById(curNodeId);
const newNodeData: BehaviorNodeModel = {
id: this.autoId++,
@@ -311,15 +316,17 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
}
this.onSelectNode(null);
this.pushUndoStack();
const rootData = this.graph.findDataById("1");
const parentData = Utils.findParent(rootData, curNodeId);
parentData.children = parentData.children.filter((e) => e.id != curNodeId);
this.changeWithoutAnim();
}
updateNode(id: string) {
this.graph.changeData();
this.graph.layout();
pushUndoStack() {
this.undoStack.push(Utils.cloneNodeData(this.graph.findDataById('1') as GraphNodeModel));
console.log("push", this.undoStack);
this.redoStack = [];
}
changeWithoutAnim() {
@@ -366,7 +373,8 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
if (!str || str == "") {
return;
}
const data = Utils.createTreeData(JSON.parse(str), this.state.settings);
this.pushUndoStack();
const data = Utils.createTreeData(JSON.parse(str), this.state.settings);
this.autoId = Utils.refreshNodeId(data, this.autoId);
this.onSelectNode(null);
if (!curNodeData.children) {
@@ -381,6 +389,30 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
}
}
undo() {
if (this.undoStack.length == 0) {
return;
}
const data = this.undoStack.pop();
this.graph.set("animate", false);
this.graph.changeData(Utils.createTreeData(data, this.state.settings));
this.graph.layout();
this.graph.set("animate", true);
this.redoStack.push(data);
}
redo() {
if (this.redoStack.length == 0) {
return;
}
const data = this.redoStack.pop();
this.graph.set("animate", false);
this.graph.changeData(Utils.createTreeData(data, this.state.settings));
this.graph.layout();
this.graph.set("animate", true);
this.undoStack.push(data);
}
render() {
const { curNodeId, treeModel, settings } = this.state;
var curNode: any;
@@ -399,6 +431,7 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
settings={settings}
updateNode={(id, forceUpdate) => {
if (forceUpdate) {
this.pushUndoStack();
const data: any = this.graph.findDataById(id);
data.conf = settings.getNodeConf(data.name);
data.size = Utils.calcTreeNodeSize(data);
+10
View File
@@ -62,6 +62,16 @@ export default class TreeTabs extends Component<TreeTabsProps, TreeTabsState> {
}
message.success("已保存所有行为树");
});
ipcRenderer.on(MainEventType.UNDO, () => {
const editor = this.getCurEditor();
editor?.undo();
});
ipcRenderer.on(MainEventType.REDO, () => {
const editor = this.getCurEditor();
editor?.redo();
});
}
getOpenTreesModel() {