Files
2024-11-28 17:51:53 +05:30

693 lines
18 KiB
JavaScript

LiteGraph.use_uuids = true
LiteGraph.uuidv4 = function() { return Date.now() }
LGraph.prototype.getGroupByUUID = function (uuid) {
let groups = this._groups
let group = null
for (let index = 0; index < groups.length; index++) {
let tgroup = groups[index];
if (tgroup.uuid && tgroup.uuid == uuid) {
group = tgroup
break
}
}
return group
}
LGraph.prototype.getGroupIndexByUUID = function (uuid) {
let groups = this._groups
let at = -1
for (let index = 0; index < groups.length; index++) {
let tgroup = groups[index];
if (tgroup.uuid && tgroup.uuid == uuid) {
at = index
break
}
}
return at
}
LGraph.prototype.add = function (node, skip_compute_order) {
if (!node) {
return;
}
//groups
if (node.constructor === LGraphGroup) {
this._groups.push(node);
this.setDirtyCanvas(true);
this.change();
if(!node.uuid) {
node.uuid = LiteGraph.uuidv4()
}
node.graph = this;
this._version++;
if (this.onGroupAdded)
this.onGroupAdded(node)
return;
}
//nodes
if (node.id != -1 && this._nodes_by_id[node.id] != null) {
console.warn(
"Nexus LiteGraph: there is already a node with this ID, will reuse it"
);
if (LiteGraph.use_uuids) {
node.id = LiteGraph.uuidv4()
}
else {
node.id = ++this.last_node_id;
}
}
if (this._nodes.length >= LiteGraph.MAX_NUMBER_OF_NODES) {
throw "LiteGraph: max number of nodes in a graph reached";
}
//give him an id
if (LiteGraph.use_uuids) {
if (node.id == null || node.id == -1)
node.id = LiteGraph.uuidv4();
let uuid = localStorage.getItem('nexus-socket-uuid');
if (uuid) {
node.properties.owner = uuid
}
this.last_node_id = node.id;
}
else {
if (node.id == null || node.id == -1) {
node.id = ++this.last_node_id;
} else if (this.last_node_id < node.id) {
this.last_node_id = node.id;
}
}
node.graph = this;
this._version++;
this._nodes.push(node);
this._nodes_by_id[node.id] = node;
if (node.onAdded) {
node.onAdded(this);
}
if (this.config.align_to_grid) {
node.alignToGrid();
}
if (!skip_compute_order) {
this.updateExecutionOrder();
}
if (this.onNodeAdded) {
this.onNodeAdded(node);
}
this.setDirtyCanvas(true);
this.change();
return node; //to chain actions
};
LGraph.prototype.addNexus = function (node, skip_compute_order) {
if (!node) {
return;
}
//groups
if (node.constructor === LGraphGroup) {
this._groups.push(node);
this.setDirtyCanvas(true);
this.change();
// node.id = LiteGraph.uuidv4();
node.graph = this;
this._version++;
return;
}
// //nodes
// if (node.id != -1 && this._nodes_by_id[node.id] != null) {
// console.warn(
// "Nexus LiteGraph: there is already a node with this ID, will reuse it"
// );
// if (LiteGraph.use_uuids) {
// node.id = LiteGraph.uuidv4();
// }
// else {
// node.id = ++this.last_node_id;
// }
// }
if (this._nodes.length >= LiteGraph.MAX_NUMBER_OF_NODES) {
throw "LiteGraph: max number of nodes in a graph reached";
}
//give him an id
// if (LiteGraph.use_uuids) {
// if (node.id == null || node.id == -1)
// let uuid = localStorage.getItem('nexus-socket-uuid');
// if (uuid) {
// node.properties.owner = uuid
// }
// node.id = LiteGraph.uuidv4();
// }
// else {
// if (node.id == null || node.id == -1) {
// node.id = ++this.last_node_id;
// } else if (this.last_node_id < node.id) {
this.last_node_id = node.id;
// }
// }
node.graph = this;
this._version++;
this._nodes.push(node);
this._nodes_by_id[node.id] = node;
if (this.config.align_to_grid) {
node.alignToGrid();
}
if (!skip_compute_order) {
this.updateExecutionOrder();
}
if (this.onNodeAddedNexus) {
this.onNodeAddedNexus(node);
}
this.setDirtyCanvas(true);
this.change();
return node; //to chain actions
};
LGraph.prototype.remove = function (node) {
if (node.constructor === LiteGraph.LGraphGroup) {
var index = this._groups.indexOf(node);
if (index != -1) {
this._groups.splice(index, 1);
}
node.graph = null;
this._version++;
this.setDirtyCanvas(true, true);
this.change();
if (this.onGroupRemoved)
this.onGroupRemoved(node)
return;
}
if (this._nodes_by_id[node.id] == null) {
return;
} //not found
if (node.ignore_remove) {
return;
} //cannot be removed
this.beforeChange(); //sure? - almost sure is wrong
//disconnect inputs
if (node.inputs) {
for (var i = 0; i < node.inputs.length; i++) {
var slot = node.inputs[i];
if (slot.link != null) {
node.disconnectInput(i);
}
}
}
//disconnect outputs
if (node.outputs) {
for (var i = 0; i < node.outputs.length; i++) {
var slot = node.outputs[i];
if (slot.links != null && slot.links.length) {
node.disconnectOutput(i);
}
}
}
//node.id = -1; //why?
//callback
if (node.onRemoved) {
node.onRemoved();
}
node.graph = null;
this._version++;
//remove from canvas render
if (this.list_of_graphcanvas) {
for (var i = 0; i < this.list_of_graphcanvas.length; ++i) {
var canvas = this.list_of_graphcanvas[i];
if (canvas.selected_nodes[node.id]) {
delete canvas.selected_nodes[node.id];
}
if (canvas.node_dragged == node) {
canvas.node_dragged = null;
}
}
}
//remove from containers
var pos = this._nodes.indexOf(node);
if (pos != -1) {
this._nodes.splice(pos, 1);
}
delete this._nodes_by_id[node.id];
if (this.onNodeRemoved) {
this.onNodeRemoved(node);
}
//close panels
this.sendActionToCanvas("checkPanels");
this.setDirtyCanvas(true, true);
this.afterChange(); //sure? - almost sure is wrong
this.change();
this.updateExecutionOrder();
};
LGraph.prototype.removeNexus = function (node) {
if (node.constructor === LiteGraph.LGraphGroup) {
var index = this._groups.indexOf(node);
if (index != -1) {
this._groups.splice(index, 1);
}
node.graph = null;
this._version++;
this.setDirtyCanvas(true, true);
this.change();
return;
}
if (this._nodes_by_id[node.id] == null) {
return;
} //not found
if (node.ignore_remove) {
return;
} //cannot be removed
this.beforeChange(); //sure? - almost sure is wrong
//disconnect inputs
if (node.inputs) {
for (var i = 0; i < node.inputs.length; i++) {
var slot = node.inputs[i];
if (slot.link != null) {
node.disconnectInput(i);
}
}
}
//disconnect outputs
if (node.outputs) {
for (var i = 0; i < node.outputs.length; i++) {
var slot = node.outputs[i];
if (slot.links != null && slot.links.length) {
node.disconnectOutput(i);
}
}
}
//node.id = -1; //why?
//callback
if (node.onRemoved) {
node.onRemoved();
}
node.graph = null;
this._version++;
//remove from canvas render
if (this.list_of_graphcanvas) {
for (var i = 0; i < this.list_of_graphcanvas.length; ++i) {
var canvas = this.list_of_graphcanvas[i];
if (canvas.selected_nodes[node.id]) {
delete canvas.selected_nodes[node.id];
}
if (canvas.node_dragged == node) {
canvas.node_dragged = null;
}
}
}
//remove from containers
var pos = this._nodes.indexOf(node);
if (pos != -1) {
this._nodes.splice(pos, 1);
}
delete this._nodes_by_id[node.id];
//close panels
this.sendActionToCanvas("checkPanels");
this.setDirtyCanvas(true, true);
this.afterChange(); //sure? - almost sure is wrong
this.change();
this.updateExecutionOrder();
};
LGraphNode.prototype.configureNexus = function (info) {
if (this.graph) {
this.graph._version++;
}
for (var j in info) {
if (j == "properties") {
//i don't want to clone properties, I want to reuse the old container
for (var k in info.properties) {
this.properties[k] = info.properties[k];
}
continue;
}
if (info[j] == null) {
continue;
} else if (typeof info[j] == "object") {
//object
if (this[j] && this[j].configure) {
this[j].configure(info[j]);
} else {
this[j] = LiteGraph.cloneObject(info[j], this[j]);
}
} //value
else {
this[j] = info[j];
}
}
if (!info.title) {
this.title = this.constructor.title;
}
if (this.inputs) {
for (var i = 0; i < this.inputs.length; ++i) {
var input = this.inputs[i];
if (this.onInputAdded)
this.onInputAdded(input);
}
}
if (this.outputs) {
for (var i = 0; i < this.outputs.length; ++i) {
var output = this.outputs[i];
if (!output.links) {
continue;
}
if (this.onOutputAdded)
this.onOutputAdded(output);
}
}
if (this.widgets) {
for (var i = 0; i < this.widgets.length; ++i) {
var w = this.widgets[i];
if (!w)
continue;
if (w.options && w.options.property && (this.properties[w.options.property] != undefined))
w.value = JSON.parse(JSON.stringify(this.properties[w.options.property]));
}
if (info.widgets_values) {
for (var i = 0; i < info.widgets_values.length; ++i) {
if (this.widgets[i]) {
this.widgets[i].value = info.widgets_values[i];
}
}
}
}
if (this.onConfigure) {
this.onConfigure(info);
}
};
LGraphCanvas.prototype.selectNodesNexus = function (nodes, add_to_current_selection) {
if (!add_to_current_selection) {
this.deselectAllNodes();
}
nodes = nodes || this.graph._nodes;
if (typeof nodes == "string") nodes = [nodes];
for (var i in nodes) {
var node = nodes[i];
if (node.is_selected) {
this.deselectNode(node);
continue;
}
if (!node.is_selected && node.onSelected) {
node.onSelected();
}
node.is_selected = true;
this.selected_nodes[node.id] = node;
if (node.inputs) {
for (var j = 0; j < node.inputs.length; ++j) {
this.highlighted_links[node.inputs[j].link] = true;
}
}
if (node.outputs) {
for (var j = 0; j < node.outputs.length; ++j) {
var out = node.outputs[j];
if (out.links) {
for (var k = 0; k < out.links.length; ++k) {
this.highlighted_links[out.links[k]] = true;
}
}
}
}
}
this.setDirty(true);
};
LGraphCanvas.prototype.deselectNodeNexus = function(node) {
if (!node.is_selected) {
return;
}
if (node.onDeselected) {
node.onDeselected();
}
node.is_selected = false;
//remove highlighted
if (node.inputs) {
for (var i = 0; i < node.inputs.length; ++i) {
delete this.highlighted_links[node.inputs[i].link];
}
}
if (node.outputs) {
for (var i = 0; i < node.outputs.length; ++i) {
var out = node.outputs[i];
if (out.links) {
for (var j = 0; j < out.links.length; ++j) {
delete this.highlighted_links[out.links[j]];
}
}
}
}
};
LGraphGroup.prototype.move = function (deltax, deltay, ignore_nodes) {
this._pos[0] += deltax;
this._pos[1] += deltay;
if (ignore_nodes) {
return;
}
for (var i = 0; i < this._nodes.length; ++i) {
var node = this._nodes[i];
node.pos[0] += deltax;
node.pos[1] += deltay;
if (this.onGroupNodeMoved)
this.onGroupNodeMoved(node)
}
if (this.onGroupMoved)
this.onGroupMoved(this)
};
LGraphGroup.prototype.configure = function (o) {
this.title = o.title;
this.owner = o.owner;
this.uuid = o.uuid;
this._bounding.set(o.bounding);
this.color = o.color;
if (o.font_size) {
this.font_size = o.font_size;
}
};
LGraphGroup.prototype.serialize = function () {
var b = this._bounding;
return {
title: this.title,
bounding: [
Math.round(b[0]),
Math.round(b[1]),
Math.round(b[2]),
Math.round(b[3])
],
uuid: this.uuid,
color: this.color,
font_size: this.font_size
};
};
LGraph.prototype.addNode = function (nodeData) {
let node = LiteGraph.createNode(nodeData.type, nodeData.title);
if (!node) {
console.warn("Node type not found: " + nodeData.type);
return false;
}
node.id = nodeData.id;
node.configureNexus(nodeData);
this.addNexus(node);
return true;
};
LGraph.prototype.removeNode = function (data) {
let node = this.getNodeById(data.id);
if (!node) {
console.warn("Node ID not found: " + data);
return false;
}
this.removeNexus(node);
return true;
};
LGraph.prototype.addLink = function (linkData) {
let link = new LiteGraph.LLink();
link.configure(linkData);
this.links[link.id] = link;
return;
};
LGraph.prototype.addGroup = function (data) {
var group = new LiteGraph.LGraphGroup();
group.configure(data);
this._groups.push(group);
this.setDirtyCanvas(true);
this.change();
group.graph = this;
this._version++;
if (this.onGroupAdded)
this.onGroupAdded(group)
return;
};
LGraph.prototype.removeGroup = function (group) {
let existingGroupIndex = this.getGroupIndexByUUID(group.uuid);
if (existingGroupIndex != -1) {
this._groups.splice(existingGroupIndex, 1);
}
group.graph = null;
this._version++;
this.setDirtyCanvas(true, true);
this.change();
return;
};
LGraph.prototype.updateNode = function (nodeData, type = "all") {
let existingNode = this.getNodeById(nodeData.id);
if (existingNode) {
if (type == "all") {
existingNode.configureNexus(nodeData);
} else if (type == "widgets") {
if (existingNode.widgets) {
for (var i = 0; i < existingNode.widgets.length; ++i) {
var w = existingNode.widgets[i];
if (!w)
continue;
if (w.options && w.options.property && (existingNode.properties[w.options.property] != undefined))
w.value = JSON.parse(JSON.stringify(existingNode.properties[w.options.property]));
}
if (nodeData.widgets_values) {
for (var i = 0; i < nodeData.widgets_values.length; ++i) {
if (existingNode.widgets[i]) {
existingNode.widgets[i].value = nodeData.widgets_values[i];
}
}
}
}
}
} else {
this.addNode(nodeData);
}
};
LGraph.prototype.updateLink = function (linkData) {
if (linkData) {
let id
if (linkData instanceof Object) {
id = linkData.id
} else {
id = linkData[0]
}
let existingLink = this.links[id];
if (existingLink) {
existingLink.configure(linkData);
} else {
this.addLink(linkData);
}
}
};
LGraph.prototype.updateLinkManual = function (change, linkData, node, graph) {
if (change == "add") {
this.updateLink(linkData)
} else if (change == "remove") {
let existingLink = this.links[linkData[0]];
if (existingLink) {
this.removeLink(linkData[0])
delete this.links[linkData[0]]
}
}
if (node) {
this.updateNode(node)
}
graph.updateExecutionOrder();
graph._version++;
graph.setDirtyCanvas(true, true);
};
LGraph.prototype.updateGroup = function (groupData) {
let existingGroup = this.getGroupByUUID(groupData.uuid);
if (existingGroup) {
existingGroup.configure(groupData);
} else {
this.addGroup(groupData);
}
};
LGraph.prototype.updateNodes = function (newNodes) {
newNodes.forEach(nodeData => this.updateNode(nodeData));
};
LGraph.prototype.updateLinks = function (newLinks) {
newLinks.forEach(linkData => this.updateLink(linkData));
};
LGraph.prototype.updateGroups = function (newGroups) {
newGroups.forEach(groupData => this.updateGroup(groupData));
};