undo & redo
This commit is contained in:
1 parent
8c6991afb3
commit
d87cba3622
6 files changed
+75
-9
No files matched your search
@@ -53,8 +53,6 @@ npm run dist # 编译exe可执行文件
|
||||
+ js/ts版本 计划中。
|
||||
|
||||
## TODO
|
||||
+ 历史记录(撤销/恢复)
|
||||
+ 资源面板支持树型结构
|
||||
+ 右键菜单
|
||||
|
||||
## About
|
||||
|
||||
@@ -10,4 +10,6 @@ export default {
|
||||
SAVE: "SAVE",
|
||||
SAVE_ALL: "SAVE_ALL",
|
||||
RELOAD_SERVER: "RELOAD_SERVER",
|
||||
UNDO: "UNDO",
|
||||
REDO: "REDO",
|
||||
};
|
||||
+26
-3
@@ -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
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "behavior3editor",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"description": "行为树编辑器",
|
||||
"main": "./dist/main.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -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,6 +373,7 @@ export default class Editor extends React.Component<EditorProps, EditorState> {
|
||||
if (!str || str == "") {
|
||||
return;
|
||||
}
|
||||
this.pushUndoStack();
|
||||
const data = Utils.createTreeData(JSON.parse(str), this.state.settings);
|
||||
this.autoId = Utils.refreshNodeId(data, this.autoId);
|
||||
this.onSelectNode(null);
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in new issue
Block a user