feat: implement delete with restore edges

This commit is contained in:
max_richter 2024-03-21 12:48:08 +01:00
parent 8dfd05fc63
commit 2629008447
3 changed files with 64 additions and 19 deletions

View File

@ -522,10 +522,11 @@
event.key === "x") && event.key === "x") &&
bodyIsFocused bodyIsFocused
) { ) {
graph.startUndoGroup();
if ($activeNodeId !== -1) { if ($activeNodeId !== -1) {
const node = graph.getNode($activeNodeId); const node = graph.getNode($activeNodeId);
if (node) { if (node) {
graph.removeNode(node); graph.removeNode(node, { restoreEdges: event.ctrlKey });
$activeNodeId = -1; $activeNodeId = -1;
} }
} }
@ -533,12 +534,13 @@
for (const nodeId of $selectedNodes) { for (const nodeId of $selectedNodes) {
const node = graph.getNode(nodeId); const node = graph.getNode(nodeId);
if (node) { if (node) {
graph.removeNode(node); graph.removeNode(node, { restoreEdges: event.ctrlKey });
} }
} }
$selectedNodes.clear(); $selectedNodes.clear();
$selectedNodes = $selectedNodes; $selectedNodes = $selectedNodes;
} }
graph.saveUndoGroup();
} }
} }

View File

@ -79,6 +79,6 @@
height: 0px; height: 0px;
transform: scale(calc(var(--cz) * 0.1)); transform: scale(calc(var(--cz) * 0.1));
display: var(--node-display, block); display: var(--node-display, block);
opacity: calc((var(--cz) - 2) / 5); opacity: calc((var(--cz) - 2.5) / 3.5);
} }
</style> </style>

View File

@ -18,6 +18,8 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
private _edges: Edge[] = []; private _edges: Edge[] = [];
edges: Writable<Edge[]> = writable([]); edges: Writable<Edge[]> = writable([]);
currentUndoGroup: number | null = null;
inputSockets: Writable<Set<string>> = writable(new Set()); inputSockets: Writable<Set<string>> = writable(new Set());
history: HistoryManager = new HistoryManager(this); history: HistoryManager = new HistoryManager(this);
@ -188,9 +190,31 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
} }
} }
removeNode(node: Node) { removeNode(node: Node, { restoreEdges = false } = {}) {
const edges = this._edges.filter((edge) => edge[0].id !== node.id && edge[2].id !== node.id);
this.edges.set(edges); const edgesToNode = this._edges.filter((edge) => edge[2].id === node.id);
const edgesFromNode = this._edges.filter((edge) => edge[0].id === node.id);
for (const edge of [...edgesToNode, ...edgesFromNode]) {
this.removeEdge(edge, { applyDeletion: false });
}
if (restoreEdges) {
const outputSockets = edgesToNode.map(e => [e[0], e[1]] as const);
const inputSockets = edgesFromNode.map(e => [e[2], e[3]] as const);
for (const [to, toSocket] of inputSockets) {
for (const [from, fromSocket] of outputSockets) {
const outputType = from.tmp?.type?.outputs?.[fromSocket];
const inputType = to?.tmp?.type?.inputs?.[toSocket]?.type;
if (outputType === inputType) {
this.createEdge(from, fromSocket, to, toSocket, { applyUpdate: false });
continue;
}
}
}
}
this.edges.set(this._edges);
this.nodes.update((nodes) => { this.nodes.update((nodes) => {
nodes.delete(node.id); nodes.delete(node.id);
@ -222,7 +246,7 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
this.save(); this.save();
} }
createEdge(from: Node, fromSocket: number, to: Node, toSocket: string) { createEdge(from: Node, fromSocket: number, to: Node, toSocket: string, { applyUpdate = true } = {}) {
const existingEdges = this.getEdgesToNode(to); const existingEdges = this.getEdgesToNode(to);
@ -245,12 +269,16 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
const edgeToBeReplaced = this._edges.find(e => e[2].id === to.id && e[3] === toSocket); const edgeToBeReplaced = this._edges.find(e => e[2].id === to.id && e[3] === toSocket);
if (edgeToBeReplaced) { if (edgeToBeReplaced) {
this.removeEdge(edgeToBeReplaced); this.removeEdge(edgeToBeReplaced, { applyDeletion: applyUpdate });
} }
this.edges.update((edges) => { if (applyUpdate) {
return [...edges, [from, fromSocket, to, toSocket]]; this.edges.update((edges) => {
}); return [...edges, [from, fromSocket, to, toSocket]];
});
} else {
this._edges.push([from, fromSocket, to, toSocket]);
}
from.tmp = from.tmp || {}; from.tmp = from.tmp || {};
from.tmp.children = from.tmp.children || []; from.tmp.children = from.tmp.children || [];
@ -261,10 +289,22 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
to.tmp.parents.push(from); to.tmp.parents.push(from);
this.execute(); this.execute();
if (applyUpdate) {
this.save();
}
}
startUndoGroup() {
this.currentUndoGroup = 1;
}
saveUndoGroup() {
this.currentUndoGroup = null;
this.save(); this.save();
} }
save() { save() {
if (this.currentUndoGroup) return;
this.emit("save", this.serialize()); this.emit("save", this.serialize());
this.history.save(); this.history.save();
} }
@ -341,7 +381,7 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
} }
removeEdge(edge: Edge) { removeEdge(edge: Edge, { applyDeletion = true }: { applyDeletion?: boolean } = {}) {
const id0 = edge[0].id; const id0 = edge[0].id;
const sid0 = edge[1]; const sid0 = edge[1];
const id2 = edge[2].id; const id2 = edge[2].id;
@ -350,10 +390,6 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
const _edge = this._edges.find((e) => e[0].id === id0 && e[1] === sid0 && e[2].id === id2 && e[3] === sid2); const _edge = this._edges.find((e) => e[0].id === id0 && e[1] === sid0 && e[2].id === id2 && e[3] === sid2);
if (!_edge) return; if (!_edge) return;
this.edges.update((edges) => {
return edges.filter(e => e !== _edge);
});
edge[0].tmp = edge[0].tmp || {}; edge[0].tmp = edge[0].tmp || {};
if (edge[0].tmp.children) { if (edge[0].tmp.children) {
edge[0].tmp.children = edge[0].tmp.children.filter(n => n.id !== id2); edge[0].tmp.children = edge[0].tmp.children.filter(n => n.id !== id2);
@ -364,8 +400,16 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
edge[2].tmp.parents = edge[2].tmp.parents.filter(n => n.id !== id0); edge[2].tmp.parents = edge[2].tmp.parents.filter(n => n.id !== id0);
} }
this.execute(); if (applyDeletion) {
this.save(); this.edges.update((edges) => {
return edges.filter(e => e !== _edge);
});
this.execute();
this.save();
} else {
this._edges = this._edges.filter(e => e !== _edge);
}
} }
getEdgesToNode(node: Node) { getEdgesToNode(node: Node) {
@ -402,7 +446,6 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
throw new Error(`Template not found: ${template}`); throw new Error(`Template not found: ${template}`);
} }
} }
} }