feat: implement delete with restore edges
This commit is contained in:
parent
8dfd05fc63
commit
2629008447
@ -522,10 +522,11 @@
|
||||
event.key === "x") &&
|
||||
bodyIsFocused
|
||||
) {
|
||||
graph.startUndoGroup();
|
||||
if ($activeNodeId !== -1) {
|
||||
const node = graph.getNode($activeNodeId);
|
||||
if (node) {
|
||||
graph.removeNode(node);
|
||||
graph.removeNode(node, { restoreEdges: event.ctrlKey });
|
||||
$activeNodeId = -1;
|
||||
}
|
||||
}
|
||||
@ -533,12 +534,13 @@
|
||||
for (const nodeId of $selectedNodes) {
|
||||
const node = graph.getNode(nodeId);
|
||||
if (node) {
|
||||
graph.removeNode(node);
|
||||
graph.removeNode(node, { restoreEdges: event.ctrlKey });
|
||||
}
|
||||
}
|
||||
$selectedNodes.clear();
|
||||
$selectedNodes = $selectedNodes;
|
||||
}
|
||||
graph.saveUndoGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,6 @@
|
||||
height: 0px;
|
||||
transform: scale(calc(var(--cz) * 0.1));
|
||||
display: var(--node-display, block);
|
||||
opacity: calc((var(--cz) - 2) / 5);
|
||||
opacity: calc((var(--cz) - 2.5) / 3.5);
|
||||
}
|
||||
</style>
|
||||
|
@ -18,6 +18,8 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
private _edges: Edge[] = [];
|
||||
edges: Writable<Edge[]> = writable([]);
|
||||
|
||||
currentUndoGroup: number | null = null;
|
||||
|
||||
inputSockets: Writable<Set<string>> = writable(new Set());
|
||||
|
||||
history: HistoryManager = new HistoryManager(this);
|
||||
@ -188,9 +190,31 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
}
|
||||
}
|
||||
|
||||
removeNode(node: Node) {
|
||||
const edges = this._edges.filter((edge) => edge[0].id !== node.id && edge[2].id !== node.id);
|
||||
this.edges.set(edges);
|
||||
removeNode(node: Node, { restoreEdges = false } = {}) {
|
||||
|
||||
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) => {
|
||||
nodes.delete(node.id);
|
||||
@ -222,7 +246,7 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
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);
|
||||
|
||||
@ -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);
|
||||
if (edgeToBeReplaced) {
|
||||
this.removeEdge(edgeToBeReplaced);
|
||||
this.removeEdge(edgeToBeReplaced, { applyDeletion: applyUpdate });
|
||||
}
|
||||
|
||||
if (applyUpdate) {
|
||||
this.edges.update((edges) => {
|
||||
return [...edges, [from, fromSocket, to, toSocket]];
|
||||
});
|
||||
} else {
|
||||
this._edges.push([from, fromSocket, to, toSocket]);
|
||||
}
|
||||
|
||||
from.tmp = from.tmp || {};
|
||||
from.tmp.children = from.tmp.children || [];
|
||||
@ -261,10 +289,22 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
to.tmp.parents.push(from);
|
||||
|
||||
this.execute();
|
||||
if (applyUpdate) {
|
||||
this.save();
|
||||
}
|
||||
}
|
||||
|
||||
startUndoGroup() {
|
||||
this.currentUndoGroup = 1;
|
||||
}
|
||||
|
||||
saveUndoGroup() {
|
||||
this.currentUndoGroup = null;
|
||||
this.save();
|
||||
}
|
||||
|
||||
save() {
|
||||
if (this.currentUndoGroup) return;
|
||||
this.emit("save", this.serialize());
|
||||
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 sid0 = edge[1];
|
||||
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);
|
||||
if (!_edge) return;
|
||||
|
||||
this.edges.update((edges) => {
|
||||
return edges.filter(e => e !== _edge);
|
||||
});
|
||||
|
||||
edge[0].tmp = edge[0].tmp || {};
|
||||
if (edge[0].tmp.children) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (applyDeletion) {
|
||||
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) {
|
||||
@ -402,7 +446,6 @@ export class GraphManager extends EventEmitter<{ "save": Graph }> {
|
||||
throw new Error(`Template not found: ${template}`);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user