diff --git a/build/litegraph.js b/build/litegraph.js
index fe597ccbd..a8c6aacfb 100644
--- a/build/litegraph.js
+++ b/build/litegraph.js
@@ -25,7 +25,7 @@ var LiteGraph = {
NODE_DEFAULT_BOXCOLOR: "#AEF",
NODE_DEFAULT_SHAPE: "box",
MAX_NUMBER_OF_NODES: 1000, //avoid infinite loops
- DEFAULT_POSITION: [100,100],
+ DEFAULT_POSITION: [100,100],//default node position
node_images_path: "",
debug: false,
@@ -87,45 +87,6 @@ var LiteGraph = {
var node = new base_class( name );
- /*
- if (base_class.prototype) //is a class
- {
- node = new base_class(name);
- }
- else
- {
- node = new LGraphNode(name);
- node.inputs = [];
- node.outputs = [];
-
- //add inputs and outputs
- for (var i in prototype)
- {
- if(i == "inputs")
- {
- for(var j in prototype[i])
- node.addInput( prototype[i][j][0],prototype[i][j][1], prototype[i][j][2] );
- }
- else if(i == "outputs")
- {
- for(var j in prototype[i])
- node.addOutput( prototype[i][j][0],prototype[i][j][1], prototype[i][j][2] );
- }
- else
- {
- if( prototype[i].concat ) //array
- node[i] = prototype[i].concat();
- else if (typeof(prototype[i]) == 'object')
- node[i] = LiteGraph.cloneObject(prototype[i]); //slow but safe
- else
- node[i] = prototype[i];
- }
- }
- //set size
- if(base_class.size) node.size = base_class.size.concat(); //save size
- }
- */
-
node.type = type;
if(!node.title) node.title = title;
if(!node.flags) node.flags = {};
@@ -299,7 +260,7 @@ LGraph.prototype.clear = function()
//links
this.last_link_id = 0;
- this.links = {};
+ this.links = {}; //container with all the links
//iterations
this.iteration = 0;
@@ -513,20 +474,22 @@ LGraph.prototype.computeExecutionOrder = function()
//for every connection
for(var j = 0; j < output.links.length; j++)
{
- var link = output.links[j];
+ var link_id = output.links[j];
+ var link = this.links[link_id];
+ if(!link) continue;
//already visited link (ignore it)
- if(visited_links[ link[0] ])
+ if(visited_links[ link.id ])
continue;
- var target_node = this.getNodeById( link[3] );
+ var target_node = this.getNodeById( link.target_id );
if(target_node == null)
{
- visited_links[ link[0] ] = true;
+ visited_links[ link.id ] = true;
continue;
}
- visited_links[link[0]] = true; //mark as visited
+ visited_links[link.id] = true; //mark as visited
remaining_links[target_node.id] -= 1; //reduce the number of links remaining
if (remaining_links[target_node.id] == 0)
S.push(target_node); //if no more links, then add to Starters array
@@ -617,7 +580,7 @@ LGraph.prototype.sendActionToCanvas = function(action, params)
* @param {LGraphNode} node the instance of the node
*/
-LGraph.prototype.add = function(node)
+LGraph.prototype.add = function(node, skip_compute_order)
{
if(!node || (node.id != -1 && this._nodes_by_id[node.id] != null))
return; //already added
@@ -645,8 +608,9 @@ LGraph.prototype.add = function(node)
if(this.config.align_to_grid)
node.alignToGrid();
-
- this.updateExecutionOrder();
+
+ if(!skip_compute_order)
+ this.updateExecutionOrder();
if(this.onNodeAdded)
this.onNodeAdded(node);
@@ -928,6 +892,11 @@ LGraph.prototype.serialize = function()
for (var i in this._nodes)
nodes_info.push( this._nodes[i].serialize() );
+ //remove data from links, we dont want to store it
+ for (var i in this.links)
+ this.links[i].data = null;
+
+
var data = {
graph: this.graph,
@@ -935,6 +904,7 @@ LGraph.prototype.serialize = function()
frame: this.frame,
last_node_id: this.last_node_id,
last_link_id: this.last_link_id,
+ links: LiteGraph.cloneObject( this.links ),
config: this.config,
nodes: nodes_info
@@ -967,8 +937,8 @@ LGraph.prototype.configure = function(data, keep_old)
for (var i in nodes)
{
var n_info = nodes[i]; //stored info
- var n = LiteGraph.createNode( n_info.type, n_info.title );
- if(!n)
+ var node = LiteGraph.createNode( n_info.type, n_info.title );
+ if(!node)
{
if(LiteGraph.debug)
console.log("Node not found: " + n_info.type);
@@ -976,10 +946,12 @@ LGraph.prototype.configure = function(data, keep_old)
continue;
}
- n.configure(n_info);
- this.add(n);
+ node.id = n_info.id; //id it or it will create a new id
+ this.add(node, true); //add before configure, otherwise configure cannot create links
+ node.configure(n_info);
}
+ this.updateExecutionOrder();
this.setDirtyCanvas(true,true);
return error;
}
@@ -1050,7 +1022,7 @@ function LGraphNode(title)
}
/**
-* configure a node from an object
+* configure a node from an object containing the serialized info
* @method configure
*/
LGraphNode.prototype.configure = function(info)
@@ -1061,39 +1033,38 @@ LGraphNode.prototype.configure = function(info)
if(info[j] == null)
continue;
- else if( info[j].concat ) //array
- this[j] = info[j].concat();
else if (typeof(info[j]) == 'object') //object
this[j] = LiteGraph.cloneObject(info[j], this[j] || {} );
else //value
this[j] = info[j];
}
-}
-/* Copy all the info from one object to this node (used for serialization) */
-LGraphNode.prototype.copyFromObject = function(info, ignore_connections)
-{
- var outputs = null;
- var inputs = null;
- var properties = null;
- var local_data = null;
-
- for (var j in info)
+ //FOR LEGACY, PLEASE REMOVE ON NEXT VERSION
+ for(var i in this.inputs)
{
- if(ignore_connections && (j == "outputs" || j == "inputs"))
+ var input = this.inputs[i];
+ if(!input.link || !input.link.length )
continue;
-
- if(j == "console") continue;
-
- if(info[j] == null)
+ var link = input.link;
+ if(typeof(link) != "object")
continue;
- else if( info[j].concat ) //array
- this[j] = info[j].concat();
- else if (typeof(info[j]) == 'object') //object
- this[j] = LiteGraph.cloneObject(info[j]);
- else //value
- this[j] = info[j];
+ input.link = link[0];
+ this.graph.links[ link[0] ] = { id: link[0], origin_id: link[1], origin_slot: link[2], target_id: link[3], target_slot: link[4] };
}
+ for(var i in this.outputs)
+ {
+ var output = this.outputs[i];
+ if(!output.links || output.links.length == 0)
+ continue;
+ for(var j in output.links)
+ {
+ var link = output.links[j];
+ if(typeof(link) != "object")
+ continue;
+ output.links[j] = link[0];
+ }
+ }
+
}
/**
@@ -1194,7 +1165,10 @@ LGraphNode.prototype.setOutputData = function(slot,data)
if(slot > -1 && slot < this.outputs.length && this.outputs[slot] && this.outputs[slot].links != null)
{
for(var i = 0; i < this.outputs[slot].links.length; i++)
- this.graph.links[ this.outputs[slot].links[i][0] ] = data;
+ {
+ var link_id = this.outputs[slot].links[i];
+ this.graph.links[ link_id ].data = data;
+ }
}
}
@@ -1208,7 +1182,7 @@ LGraphNode.prototype.getInputData = function(slot)
{
if(!this.inputs) return null;
if(slot < this.inputs.length && this.inputs[slot].link != null)
- return this.graph.links[ this.inputs[slot].link[0] ];
+ return this.graph.links[ this.inputs[slot].link ].data;
return null;
}
@@ -1280,7 +1254,7 @@ LGraphNode.prototype.getOutputNodes = function(slot)
var output = this.outputs[slot];
var r = [];
for(var i = 0; i < output.length; i++)
- r.push( this.graph.getNodeById( output.links[i][3] ));
+ r.push( this.graph.getNodeById( output.links[i].target_id ));
return r;
}
return null;
@@ -1453,7 +1427,7 @@ LGraphNode.prototype.getBounding = function()
*/
LGraphNode.prototype.isPointInsideNode = function(x,y)
{
- var margin_top = this.graph.isLive() ? 0 : 20;
+ var margin_top = this.graph && this.graph.isLive() ? 0 : 20;
if(this.flags.collapsed)
{
//if ( distance([x,y], [this.pos[0] + this.size[0]*0.5, this.pos[1] + this.size[1]*0.5]) < LiteGraph.NODE_COLLAPSED_RADIUS)
@@ -1552,12 +1526,14 @@ LGraphNode.prototype.connect = function(slot, node, target_slot)
output.type == node.inputs[target_slot].type) //same type
{
//info: link structure => [ 0:link_id, 1:start_node_id, 2:start_slot, 3:end_node_id, 4:end_slot ]
- var link = [ this.graph.last_link_id++, this.id, slot, node.id, target_slot ];
+ //var link = [ this.graph.last_link_id++, this.id, slot, node.id, target_slot ];
+ var link = { id: this.graph.last_link_id++, origin_id: this.id, origin_slot: slot, target_id: node.id, target_slot: target_slot };
+ this.graph.links[ link.id ] = link;
//connect
if( output.links == null ) output.links = [];
- output.links.push(link);
- node.inputs[target_slot].link = link;
+ output.links.push( link.id );
+ node.inputs[target_slot].link = link.id;
this.setDirtyCanvas(false,true);
this.graph.onConnectionChange();
@@ -1600,13 +1576,15 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
{
for(var i = 0, l = output.links.length; i < l; i++)
{
- var link = output.links[i];
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+
//is the link we are searching for...
- if( link[3] == target_node.id )
+ if( link_info.target_id == target_node.id )
{
output.links.splice(i,1); //remove here
- target_node.inputs[ link[4] ].link = null; //remove there
- delete this.graph.links[link[0]]; //remove the link from the links pool
+ target_node.inputs[ link_info.target_slot ].link = null; //remove there
+ delete this.graph.links[ link_id ]; //remove the link from the links pool
break;
}
}
@@ -1615,10 +1593,12 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
{
for(var i = 0, l = output.links.length; i < l; i++)
{
- var link = output.links[i];
- var target_node = this.graph.getNodeById( link[3] );
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+
+ var target_node = this.graph.getNodeById( link_info.target_id );
if(target_node)
- target_node.inputs[ link[4] ].link = null; //remove other side link
+ target_node.inputs[ link_info.target_slot ].link = null; //remove other side link
}
output.links = null;
}
@@ -1656,21 +1636,24 @@ LGraphNode.prototype.disconnectInput = function(slot)
var input = this.inputs[slot];
if(!input) return false;
- var link = this.inputs[slot].link;
+ var link_id = this.inputs[slot].link;
this.inputs[slot].link = null;
//remove other side
- var node = this.graph.getNodeById( link[1] );
+ var link_info = this.graph.links[ link_id ];
+ var node = this.graph.getNodeById( link_info.origin_id );
if(!node) return false;
- var output = node.outputs[ link[2] ];
+ var output = node.outputs[ link_info.origin_slot ];
if(!output || !output.links || output.links.length == 0)
return false;
+ //check outputs
for(var i = 0, l = output.links.length; i < l; i++)
{
- var link = output.links[i];
- if( link[3] == this.id )
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+ if( link_info.target_id == this.id )
{
output.links.splice(i,1);
break;
@@ -3438,12 +3421,15 @@ LGraphCanvas.prototype.drawConnections = function(ctx)
for(var i in node.inputs)
{
var input = node.inputs[i];
- if(!input || !input.link ) continue;
- var link = input.link;
+ if(!input || input.link == null)
+ continue;
+ var link_id = input.link;
+ var link = this.graph.links[ link_id ];
+ if(!link) continue;
- var start_node = this.graph.getNodeById( link[1] );
+ var start_node = this.graph.getNodeById( link.origin_id );
if(start_node == null) continue;
- var start_node_slot = link[2];
+ var start_node_slot = link.origin_slot;
var start_node_slotpos = null;
if(start_node_slot == -1)
diff --git a/build/litegraph.min.js b/build/litegraph.min.js
index eb3b7c41d..2e9a65eed 100644
--- a/build/litegraph.min.js
+++ b/build/litegraph.min.js
@@ -9,37 +9,39 @@ LGraph.prototype.start=function(a){if(this.status!=LGraph.STATUS_RUNNING){this.s
LGraph.prototype.stop=function(){if(this.status!=LGraph.STATUS_STOPPED){this.status=LGraph.STATUS_STOPPED;if(this.onStopEvent)this.onStopEvent();null!=this.execution_timer_id&&clearInterval(this.execution_timer_id);this.execution_timer_id=null;this.sendEventToAllNodes("onStop")}};
LGraph.prototype.runStep=function(a){a=a||1;var b=window.performance.now();this.globaltime=0.001*(b-this.starttime);try{for(var c=0;c=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(null==a.id||-1==a.id)a.id=this.last_node_id++;a.graph=this;this._nodes.push(a);this._nodes_by_id[a.id]=a;if(a.onAdded)a.onAdded();this.config.align_to_grid&&a.alignToGrid();this.updateExecutionOrder();if(this.onNodeAdded)this.onNodeAdded(a);this.setDirtyCanvas(!0);this.change();return a}};
+LGraph.prototype.add=function(a,b){if(a&&(-1==a.id||null==this._nodes_by_id[a.id])){if(this._nodes.length>=LiteGraph.MAX_NUMBER_OF_NODES)throw"LiteGraph: max number of nodes in a graph reached";if(null==a.id||-1==a.id)a.id=this.last_node_id++;a.graph=this;this._nodes.push(a);this._nodes_by_id[a.id]=a;if(a.onAdded)a.onAdded();this.config.align_to_grid&&a.alignToGrid();b||this.updateExecutionOrder();if(this.onNodeAdded)this.onNodeAdded(a);this.setDirtyCanvas(!0);this.change();return a}};
LGraph.prototype.remove=function(a){if(null!=this._nodes_by_id[a.id]&&!a.ignore_remove){if(a.inputs)for(var b=0;ba&&this.pos[1]-cb)return!0;return!1};
+LGraphNode.prototype.isPointInsideNode=function(a,b){var c=this.graph&&this.graph.isLive()?0:20;if(this.flags.collapsed){if(isInsideRectangle(a,b,this.pos[0],this.pos[1]-LiteGraph.NODE_TITLE_HEIGHT,LiteGraph.NODE_COLLAPSED_WIDTH,LiteGraph.NODE_TITLE_HEIGHT))return!0}else if(this.pos[0]-4a&&this.pos[1]-cb)return!0;return!1};
LGraphNode.prototype.findInputSlot=function(a){if(!this.inputs)return-1;for(var b=0,c=this.inputs.length;b=this.outputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(b==this)return!1;if(c.constructor===String){if(c=b.findInputSlot(c),-1==c)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+c),!1}else if(!b.inputs||c>=b.inputs.length)return LiteGraph.debug&&
-console.log("Connect: Error, slot number not found"),!1;-1!=c&&null!=b.inputs[c].link&&b.disconnectInput(c);var d=this.outputs[a];if(-1==c)null==d.links&&(d.links=[]),d.links.push({id:b.id,slot:-1});else if(0==d.type||0==b.inputs[c].type||d.type==b.inputs[c].type)a=[this.graph.last_link_id++,this.id,a,b.id,c],null==d.links&&(d.links=[]),d.links.push(a),b.inputs[c].link=a,this.setDirtyCanvas(!1,!0),this.graph.onConnectionChange();return!0};
-LGraphNode.prototype.disconnectOutput=function(a,b){if(a.constructor===String){if(a=this.findOutputSlot(a),-1==a)return LiteGraph.debug&&console.log("Connect: Error, no slot of name "+a),!1}else if(!this.outputs||a>=this.outputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;var c=this.outputs[a];if(!c.links||0==c.links.length)return!1;if(b)for(var d=0,e=c.links.length;d=this.inputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(!this.inputs[a])return!1;var b=this.inputs[a].link;this.inputs[a].link=null;a=this.graph.getNodeById(b[1]);if(!a)return!1;a=a.outputs[b[2]];if(!a||!a.links||0==a.links.length)return!1;for(var c=
-0,d=a.links.length;c=this.outputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;var c=this.outputs[a];if(!c.links||0==c.links.length)return!1;if(b)for(var d=0,e=c.links.length;d=this.inputs.length)return LiteGraph.debug&&console.log("Connect: Error, slot number not found"),!1;if(!this.inputs[a])return!1;var b=this.inputs[a].link;this.inputs[a].link=null;b=this.graph.links[b];a=this.graph.getNodeById(b.origin_id);if(!a)return!1;a=a.outputs[b.origin_slot];if(!a||!a.links||
+0==a.links.length)return!1;for(var c=0,d=a.links.length;cb&&this.inputs[b].pos?[this.pos[0]+this.inputs[b].pos[0],this.pos[1]+this.inputs[b].pos[1]]:!a&&this.outputs.length>b&&this.outputs[b].pos?[this.pos[0]+this.outputs[b].pos[0],this.pos[1]+this.outputs[b].pos[1]]:
a?[this.pos[0],this.pos[1]+10+b*LiteGraph.NODE_SLOT_HEIGHT]:[this.pos[0]+this.size[0]+1,this.pos[1]+10+b*LiteGraph.NODE_SLOT_HEIGHT]};LGraphNode.prototype.alignToGrid=function(){this.pos[0]=LiteGraph.CANVAS_GRID_SIZE*Math.round(this.pos[0]/LiteGraph.CANVAS_GRID_SIZE);this.pos[1]=LiteGraph.CANVAS_GRID_SIZE*Math.round(this.pos[1]/LiteGraph.CANVAS_GRID_SIZE)};
LGraphNode.prototype.clone=function(){var a=LiteGraph.createNode(this.type);a.size=this.size.concat();if(this.inputs)for(var b=0,c=this.inputs.length;bb[1]?0:Math.PI;a.save();a.translate(d[0],d[1]);a.rotate(f);a.beginPath();a.moveTo(-5,-5);a.lineTo(0,5);a.lineTo(5,-5);a.fill();a.restore()}}else a.beginPath(),a.moveTo(b[0],b[1]),a.lineTo(c[0],
c[1]),a.stroke()};LGraphCanvas.prototype.computeConnectionPoint=function(a,b,c){var d=distance(a,b),e=[a[0]+0.25*d,a[1]],d=[b[0]-0.25*d,b[1]],f=(1-c)*(1-c)*(1-c),g=3*(1-c)*(1-c)*c,h=3*(1-c)*c*c;c*=c*c;return[f*a[0]+g*e[0]+h*d[0]+c*b[0],f*a[1]+g*e[1]+h*d[1]+c*b[1]]};
diff --git a/css/litegraph-editor.css b/css/litegraph-editor.css
index 4147d4b87..905f5c804 100644
--- a/css/litegraph-editor.css
+++ b/css/litegraph-editor.css
@@ -102,7 +102,6 @@
background-color: #3F3F3F;
/*box-shadow: 0 0 3px black;*/
padding: 4px 10px;
- line-height: 20px;
cursor: pointer;
transition: all 1s;
-moz-transition: all 1s;
@@ -131,6 +130,12 @@
.litegraph-editor button img {
margin: -4px;
vertical-align: top;
+ opacity: 0.8;
+ transition: all 1s;
+}
+
+.litegraph-editor button:hover img {
+ opacity: 1;
}
.litegraph-editor .header button {
@@ -185,3 +190,35 @@
background-image: url('../demo/imgs/load-progress-full.png');
}
+.litegraph-editor .dialog {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-top: -150px;
+ margin-left: -200px;
+
+ background-color: #151515;
+
+ min-width: 400px;
+ min-height: 300px;
+ box-shadow: 0 0 2px black;
+}
+
+.litegraph-editor .dialog .dialog-header, .litegraph-editor .dialog .dialog-footer{
+ height: 40px;
+}
+
+.litegraph-editor .dialog .dialog-header .dialog-title {
+ font: 20px 'Arial';
+ margin: 4px;
+ padding: 4px 10px;
+ display:inline-block;
+}
+
+.litegraph-editor .dialog .dialog-content {
+ height: calc( 100% - 40px );
+ width: calc( 100% - 10px );
+ background-color: black;
+ margin: 4px;
+ display:inline-block;
+}
\ No newline at end of file
diff --git a/demo/imgs/icon-load.png b/demo/imgs/icon-load.png
new file mode 100644
index 000000000..4ab6e4e0e
Binary files /dev/null and b/demo/imgs/icon-load.png differ
diff --git a/demo/imgs/icon-save.png b/demo/imgs/icon-save.png
new file mode 100644
index 000000000..209afe833
Binary files /dev/null and b/demo/imgs/icon-save.png differ
diff --git a/demo/index.html b/demo/index.html
index 0a6b364fd..174e167a1 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -10,53 +10,6 @@
-
-
diff --git a/src/litegraph-editor.js b/src/litegraph-editor.js
index ef027c804..690238f95 100644
--- a/src/litegraph-editor.js
+++ b/src/litegraph-editor.js
@@ -21,6 +21,8 @@ function Editor(container_id, options)
graph.onAfterExecute = function() { graphcanvas.draw(true) };
//add stuff
+ this.addToolsButton("loadsession_button","Load","imgs/icon-load.png", this.onLoadButton.bind(this), ".tools-left" );
+ this.addToolsButton("savesession_button","Save","imgs/icon-save.png", this.onSaveButton.bind(this), ".tools-left" );
this.addLoadCounter();
this.addToolsButton("playnode_button","Play","imgs/icon-play.png", this.onPlayButton.bind(this), ".tools-right" );
this.addToolsButton("playstepnode_button","Step","imgs/icon-playstep.png", this.onPlayStepButton.bind(this), ".tools-right" );
@@ -64,30 +66,51 @@ Editor.prototype.addToolsButton = function(id,name,icon_url, callback, container
{
if(!container) container = ".tools";
- var button = document.createElement("button");
+ var button = this.createButton(name, icon_url);
button.id = id;
- button.innerHTML = "
"+name+"";
button.addEventListener("click", callback);
this.root.querySelector(container).appendChild(button);
-
}
-Editor.prototype.goFullscreen = function()
-{
- if(this.root.requestFullscreen)
- this.root.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- else if(this.root.mozRequestFullscreen)
- this.root.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- else if(this.root.webkitRequestFullscreen)
- this.root.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
- else
- throw("Fullscreen not supported");
- var self = this;
- setTimeout(function() {
- self.graphcanvas.resize();
- },100);
+Editor.prototype.createPanel = function(title, options)
+{
+
+ var root = document.createElement("div");
+ root.className = "dialog";
+ root.innerHTML = "";
+ root.header = root.querySelector(".dialog-header");
+ root.content = root.querySelector(".dialog-content");
+ root.footer = root.querySelector(".dialog-footer");
+
+
+ return root;
+}
+
+Editor.prototype.createButton = function(name, icon_url)
+{
+ var button = document.createElement("button");
+ if(icon_url)
+ button.innerHTML = "
";
+ button.innerHTML += name;
+ return button;
+}
+
+Editor.prototype.onLoadButton = function()
+{
+ var panel = this.createPanel("Load session");
+ var close = this.createButton("Close");
+ close.style.float = "right";
+ close.addEventListener("click", function() { panel.parentNode.removeChild( panel ); });
+ panel.header.appendChild(close);
+ panel.content.innerHTML = "test";
+
+ this.root.appendChild(panel);
+}
+
+Editor.prototype.onSaveButton = function()
+{
}
Editor.prototype.onPlayButton = function()
@@ -124,6 +147,23 @@ Editor.prototype.onLiveButton = function()
button.innerHTML = !is_live_mode ? "
Live" : "
Edit" ;
}
+Editor.prototype.goFullscreen = function()
+{
+ if(this.root.requestFullscreen)
+ this.root.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+ else if(this.root.mozRequestFullscreen)
+ this.root.requestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+ else if(this.root.webkitRequestFullscreen)
+ this.root.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
+ else
+ throw("Fullscreen not supported");
+
+ var self = this;
+ setTimeout(function() {
+ self.graphcanvas.resize();
+ },100);
+}
+
Editor.prototype.onFullscreenButton = function()
{
this.goFullscreen();
diff --git a/src/litegraph.js b/src/litegraph.js
index aae3b65ce..14ec5732f 100644
--- a/src/litegraph.js
+++ b/src/litegraph.js
@@ -24,7 +24,7 @@ var LiteGraph = {
NODE_DEFAULT_BOXCOLOR: "#AEF",
NODE_DEFAULT_SHAPE: "box",
MAX_NUMBER_OF_NODES: 1000, //avoid infinite loops
- DEFAULT_POSITION: [100,100],
+ DEFAULT_POSITION: [100,100],//default node position
node_images_path: "",
debug: false,
@@ -86,45 +86,6 @@ var LiteGraph = {
var node = new base_class( name );
- /*
- if (base_class.prototype) //is a class
- {
- node = new base_class(name);
- }
- else
- {
- node = new LGraphNode(name);
- node.inputs = [];
- node.outputs = [];
-
- //add inputs and outputs
- for (var i in prototype)
- {
- if(i == "inputs")
- {
- for(var j in prototype[i])
- node.addInput( prototype[i][j][0],prototype[i][j][1], prototype[i][j][2] );
- }
- else if(i == "outputs")
- {
- for(var j in prototype[i])
- node.addOutput( prototype[i][j][0],prototype[i][j][1], prototype[i][j][2] );
- }
- else
- {
- if( prototype[i].concat ) //array
- node[i] = prototype[i].concat();
- else if (typeof(prototype[i]) == 'object')
- node[i] = LiteGraph.cloneObject(prototype[i]); //slow but safe
- else
- node[i] = prototype[i];
- }
- }
- //set size
- if(base_class.size) node.size = base_class.size.concat(); //save size
- }
- */
-
node.type = type;
if(!node.title) node.title = title;
if(!node.flags) node.flags = {};
@@ -298,7 +259,7 @@ LGraph.prototype.clear = function()
//links
this.last_link_id = 0;
- this.links = {};
+ this.links = {}; //container with all the links
//iterations
this.iteration = 0;
@@ -512,20 +473,22 @@ LGraph.prototype.computeExecutionOrder = function()
//for every connection
for(var j = 0; j < output.links.length; j++)
{
- var link = output.links[j];
+ var link_id = output.links[j];
+ var link = this.links[link_id];
+ if(!link) continue;
//already visited link (ignore it)
- if(visited_links[ link[0] ])
+ if(visited_links[ link.id ])
continue;
- var target_node = this.getNodeById( link[3] );
+ var target_node = this.getNodeById( link.target_id );
if(target_node == null)
{
- visited_links[ link[0] ] = true;
+ visited_links[ link.id ] = true;
continue;
}
- visited_links[link[0]] = true; //mark as visited
+ visited_links[link.id] = true; //mark as visited
remaining_links[target_node.id] -= 1; //reduce the number of links remaining
if (remaining_links[target_node.id] == 0)
S.push(target_node); //if no more links, then add to Starters array
@@ -616,7 +579,7 @@ LGraph.prototype.sendActionToCanvas = function(action, params)
* @param {LGraphNode} node the instance of the node
*/
-LGraph.prototype.add = function(node)
+LGraph.prototype.add = function(node, skip_compute_order)
{
if(!node || (node.id != -1 && this._nodes_by_id[node.id] != null))
return; //already added
@@ -644,8 +607,9 @@ LGraph.prototype.add = function(node)
if(this.config.align_to_grid)
node.alignToGrid();
-
- this.updateExecutionOrder();
+
+ if(!skip_compute_order)
+ this.updateExecutionOrder();
if(this.onNodeAdded)
this.onNodeAdded(node);
@@ -927,6 +891,11 @@ LGraph.prototype.serialize = function()
for (var i in this._nodes)
nodes_info.push( this._nodes[i].serialize() );
+ //remove data from links, we dont want to store it
+ for (var i in this.links)
+ this.links[i].data = null;
+
+
var data = {
graph: this.graph,
@@ -934,6 +903,7 @@ LGraph.prototype.serialize = function()
frame: this.frame,
last_node_id: this.last_node_id,
last_link_id: this.last_link_id,
+ links: LiteGraph.cloneObject( this.links ),
config: this.config,
nodes: nodes_info
@@ -966,8 +936,8 @@ LGraph.prototype.configure = function(data, keep_old)
for (var i in nodes)
{
var n_info = nodes[i]; //stored info
- var n = LiteGraph.createNode( n_info.type, n_info.title );
- if(!n)
+ var node = LiteGraph.createNode( n_info.type, n_info.title );
+ if(!node)
{
if(LiteGraph.debug)
console.log("Node not found: " + n_info.type);
@@ -975,10 +945,12 @@ LGraph.prototype.configure = function(data, keep_old)
continue;
}
- n.configure(n_info);
- this.add(n);
+ node.id = n_info.id; //id it or it will create a new id
+ this.add(node, true); //add before configure, otherwise configure cannot create links
+ node.configure(n_info);
}
+ this.updateExecutionOrder();
this.setDirtyCanvas(true,true);
return error;
}
@@ -1049,7 +1021,7 @@ function LGraphNode(title)
}
/**
-* configure a node from an object
+* configure a node from an object containing the serialized info
* @method configure
*/
LGraphNode.prototype.configure = function(info)
@@ -1060,39 +1032,38 @@ LGraphNode.prototype.configure = function(info)
if(info[j] == null)
continue;
- else if( info[j].concat ) //array
- this[j] = info[j].concat();
else if (typeof(info[j]) == 'object') //object
this[j] = LiteGraph.cloneObject(info[j], this[j] || {} );
else //value
this[j] = info[j];
}
-}
-/* Copy all the info from one object to this node (used for serialization) */
-LGraphNode.prototype.copyFromObject = function(info, ignore_connections)
-{
- var outputs = null;
- var inputs = null;
- var properties = null;
- var local_data = null;
-
- for (var j in info)
+ //FOR LEGACY, PLEASE REMOVE ON NEXT VERSION
+ for(var i in this.inputs)
{
- if(ignore_connections && (j == "outputs" || j == "inputs"))
+ var input = this.inputs[i];
+ if(!input.link || !input.link.length )
continue;
-
- if(j == "console") continue;
-
- if(info[j] == null)
+ var link = input.link;
+ if(typeof(link) != "object")
continue;
- else if( info[j].concat ) //array
- this[j] = info[j].concat();
- else if (typeof(info[j]) == 'object') //object
- this[j] = LiteGraph.cloneObject(info[j]);
- else //value
- this[j] = info[j];
+ input.link = link[0];
+ this.graph.links[ link[0] ] = { id: link[0], origin_id: link[1], origin_slot: link[2], target_id: link[3], target_slot: link[4] };
}
+ for(var i in this.outputs)
+ {
+ var output = this.outputs[i];
+ if(!output.links || output.links.length == 0)
+ continue;
+ for(var j in output.links)
+ {
+ var link = output.links[j];
+ if(typeof(link) != "object")
+ continue;
+ output.links[j] = link[0];
+ }
+ }
+
}
/**
@@ -1193,7 +1164,10 @@ LGraphNode.prototype.setOutputData = function(slot,data)
if(slot > -1 && slot < this.outputs.length && this.outputs[slot] && this.outputs[slot].links != null)
{
for(var i = 0; i < this.outputs[slot].links.length; i++)
- this.graph.links[ this.outputs[slot].links[i][0] ] = data;
+ {
+ var link_id = this.outputs[slot].links[i];
+ this.graph.links[ link_id ].data = data;
+ }
}
}
@@ -1207,7 +1181,7 @@ LGraphNode.prototype.getInputData = function(slot)
{
if(!this.inputs) return null;
if(slot < this.inputs.length && this.inputs[slot].link != null)
- return this.graph.links[ this.inputs[slot].link[0] ];
+ return this.graph.links[ this.inputs[slot].link ].data;
return null;
}
@@ -1279,7 +1253,7 @@ LGraphNode.prototype.getOutputNodes = function(slot)
var output = this.outputs[slot];
var r = [];
for(var i = 0; i < output.length; i++)
- r.push( this.graph.getNodeById( output.links[i][3] ));
+ r.push( this.graph.getNodeById( output.links[i].target_id ));
return r;
}
return null;
@@ -1452,7 +1426,7 @@ LGraphNode.prototype.getBounding = function()
*/
LGraphNode.prototype.isPointInsideNode = function(x,y)
{
- var margin_top = this.graph.isLive() ? 0 : 20;
+ var margin_top = this.graph && this.graph.isLive() ? 0 : 20;
if(this.flags.collapsed)
{
//if ( distance([x,y], [this.pos[0] + this.size[0]*0.5, this.pos[1] + this.size[1]*0.5]) < LiteGraph.NODE_COLLAPSED_RADIUS)
@@ -1551,12 +1525,14 @@ LGraphNode.prototype.connect = function(slot, node, target_slot)
output.type == node.inputs[target_slot].type) //same type
{
//info: link structure => [ 0:link_id, 1:start_node_id, 2:start_slot, 3:end_node_id, 4:end_slot ]
- var link = [ this.graph.last_link_id++, this.id, slot, node.id, target_slot ];
+ //var link = [ this.graph.last_link_id++, this.id, slot, node.id, target_slot ];
+ var link = { id: this.graph.last_link_id++, origin_id: this.id, origin_slot: slot, target_id: node.id, target_slot: target_slot };
+ this.graph.links[ link.id ] = link;
//connect
if( output.links == null ) output.links = [];
- output.links.push(link);
- node.inputs[target_slot].link = link;
+ output.links.push( link.id );
+ node.inputs[target_slot].link = link.id;
this.setDirtyCanvas(false,true);
this.graph.onConnectionChange();
@@ -1599,13 +1575,15 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
{
for(var i = 0, l = output.links.length; i < l; i++)
{
- var link = output.links[i];
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+
//is the link we are searching for...
- if( link[3] == target_node.id )
+ if( link_info.target_id == target_node.id )
{
output.links.splice(i,1); //remove here
- target_node.inputs[ link[4] ].link = null; //remove there
- delete this.graph.links[link[0]]; //remove the link from the links pool
+ target_node.inputs[ link_info.target_slot ].link = null; //remove there
+ delete this.graph.links[ link_id ]; //remove the link from the links pool
break;
}
}
@@ -1614,10 +1592,12 @@ LGraphNode.prototype.disconnectOutput = function(slot, target_node)
{
for(var i = 0, l = output.links.length; i < l; i++)
{
- var link = output.links[i];
- var target_node = this.graph.getNodeById( link[3] );
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+
+ var target_node = this.graph.getNodeById( link_info.target_id );
if(target_node)
- target_node.inputs[ link[4] ].link = null; //remove other side link
+ target_node.inputs[ link_info.target_slot ].link = null; //remove other side link
}
output.links = null;
}
@@ -1655,21 +1635,24 @@ LGraphNode.prototype.disconnectInput = function(slot)
var input = this.inputs[slot];
if(!input) return false;
- var link = this.inputs[slot].link;
+ var link_id = this.inputs[slot].link;
this.inputs[slot].link = null;
//remove other side
- var node = this.graph.getNodeById( link[1] );
+ var link_info = this.graph.links[ link_id ];
+ var node = this.graph.getNodeById( link_info.origin_id );
if(!node) return false;
- var output = node.outputs[ link[2] ];
+ var output = node.outputs[ link_info.origin_slot ];
if(!output || !output.links || output.links.length == 0)
return false;
+ //check outputs
for(var i = 0, l = output.links.length; i < l; i++)
{
- var link = output.links[i];
- if( link[3] == this.id )
+ var link_id = output.links[i];
+ var link_info = this.graph.links[ link_id ];
+ if( link_info.target_id == this.id )
{
output.links.splice(i,1);
break;
@@ -3437,12 +3420,15 @@ LGraphCanvas.prototype.drawConnections = function(ctx)
for(var i in node.inputs)
{
var input = node.inputs[i];
- if(!input || !input.link ) continue;
- var link = input.link;
+ if(!input || input.link == null)
+ continue;
+ var link_id = input.link;
+ var link = this.graph.links[ link_id ];
+ if(!link) continue;
- var start_node = this.graph.getNodeById( link[1] );
+ var start_node = this.graph.getNodeById( link.origin_id );
if(start_node == null) continue;
- var start_node_slot = link[2];
+ var start_node_slot = link.origin_slot;
var start_node_slotpos = null;
if(start_node_slot == -1)