diff --git a/build/litegraph.js b/build/litegraph.js
index 714e7d2e0..e26094570 100644
--- a/build/litegraph.js
+++ b/build/litegraph.js
@@ -1446,6 +1446,12 @@ LGraphNode.prototype.isPointInsideNode = function(x,y)
return false;
}
+/**
+* returns the input slot with a given name (used for dynamic slots), -1 if not found
+* @method findInputSlot
+* @param {string} name the name of the slot
+* @return {number} the slot (-1 if not found)
+*/
LGraphNode.prototype.findInputSlot = function(name)
{
if(!this.inputs) return -1;
@@ -1455,6 +1461,12 @@ LGraphNode.prototype.findInputSlot = function(name)
return -1;
}
+/**
+* returns the output slot with a given name (used for dynamic slots), -1 if not found
+* @method findOutputSlot
+* @param {string} name the name of the slot
+* @return {number} the slot (-1 if not found)
+*/
LGraphNode.prototype.findOutputSlot = function(name)
{
if(!this.outputs) return -1;
@@ -1871,8 +1883,8 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas)
*
* @class LGraphCanvas
* @constructor
-* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format)
-* @param {LGraph} graph
+* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format or the canvas itself)
+* @param {LGraph} graph [optional]
*/
function LGraphCanvas(canvas, graph)
{
@@ -1897,6 +1909,12 @@ function LGraphCanvas(canvas, graph)
LGraphCanvas.link_type_colors = {'number':"#AAC",'node':"#DCA"};
+
+/**
+* clears all the data inside
+*
+* @method clear
+*/
LGraphCanvas.prototype.clear = function()
{
this.frame = 0;
@@ -1946,6 +1964,12 @@ LGraphCanvas.prototype.clear = function()
//this.UIinit();
}
+/**
+* assigns a graph, you can reasign graphs to the same canvas
+*
+* @method setGraph
+* @param {LGraph} assigns a graph
+*/
LGraphCanvas.prototype.setGraph = function(graph)
{
if(this.graph == graph) return;
@@ -1968,6 +1992,12 @@ LGraphCanvas.prototype.setGraph = function(graph)
this.setDirty(true,true);
}
+/**
+* assigns a canvas
+*
+* @method setCanvas
+* @param {Canvas} assigns a canvas
+*/
LGraphCanvas.prototype.setCanvas = function(canvas)
{
var that = this;
@@ -2006,7 +2036,7 @@ LGraphCanvas.prototype.setCanvas = function(canvas)
this._mousemove_callback = this.processMouseMove.bind(this);
this._mouseup_callback = this.processMouseUp.bind(this);
- this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this) ); //down do not need to store the binded
+ this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded
this.canvas.addEventListener("mousemove", this._mousemove_callback);
this.canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; });
@@ -2084,6 +2114,14 @@ LGraphCanvas.prototype.UIinit = function()
}
*/
+/**
+* marks as dirty the canvas, this way it will be rendered again
+*
+* @class LGraphCanvas
+* @method setDirty
+* @param {bool} fgcanvas if the foreground canvas is dirty (the one containing the nodes)
+* @param {bool} bgcanvas if the background canvas is dirty (the one containing the wires)
+*/
LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas)
{
if(fgcanvas)
@@ -2092,13 +2130,23 @@ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas)
this.dirty_bgcanvas = true;
}
-//Used to attach the canvas in a popup
+/**
+* Used to attach the canvas in a popup
+*
+* @method getCanvasWindow
+* @return {window} returns the window where the canvas is attached (the DOM root node)
+*/
LGraphCanvas.prototype.getCanvasWindow = function()
{
var doc = this.canvas.ownerDocument;
return doc.defaultView || doc.parentWindow;
}
+/**
+* starts rendering the content of the canvas when needed
+*
+* @method startRendering
+*/
LGraphCanvas.prototype.startRendering = function()
{
if(this.is_rendering) return; //already rendering
@@ -2125,6 +2173,11 @@ LGraphCanvas.prototype.startRendering = function()
*/
}
+/**
+* stops rendering the content of the canvas (to save resources)
+*
+* @method stopRendering
+*/
LGraphCanvas.prototype.stopRendering = function()
{
this.is_rendering = false;
@@ -2149,8 +2202,8 @@ LGraphCanvas.prototype.processMouseDown = function(e)
var document = ref_window.document;
this.canvas.removeEventListener("mousemove", this._mousemove_callback );
- ref_window.document.addEventListener("mousemove", this._mousemove_callback ); //catch for the entire window
- ref_window.document.addEventListener("mouseup", this._mouseup_callback );
+ ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
+ ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
var n = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes);
var skip_dragging = false;
@@ -5429,7 +5482,6 @@ function MathOperation()
this.addInput("A","number");
this.addInput("B","number");
this.addOutput("A+B","number");
- this.size = [80,20];
this.properties = {A:1.0, B:1.0};
}
@@ -5535,12 +5587,34 @@ MathCompare.prototype.onGetOutputs = function()
LiteGraph.registerNodeType("math/compare",MathCompare);
+function MathAccumulate()
+{
+ this.addInput("inc","number");
+ this.addOutput("total","number");
+ this.properties = { increment: 0, value: 0 };
+}
+
+MathAccumulate.title = "Accumulate";
+MathAccumulate.desc = "Increments a value every time";
+
+MathAccumulate.prototype.onExecute = function()
+{
+ var inc = this.getInputData(0);
+ if(inc !== null)
+ this.properties.value += inc;
+ else
+ this.properties.value += this.properties.increment;
+ this.setOutputData(0, this.properties.value );
+}
+
+LiteGraph.registerNodeType("math/accumulate", MathAccumulate);
+
//Math Trigonometry
function MathTrigonometry()
{
this.addInput("v","number");
this.addOutput("sin","number");
- this.properties = {amplitude:1.0};
+ this.properties = {amplitude:1.0, offset: 0};
this.bgImageUrl = "nodes/imgs/icon-sin.png";
}
@@ -5550,7 +5624,15 @@ MathTrigonometry.desc = "Sin Cos Tan";
MathTrigonometry.prototype.onExecute = function()
{
var v = this.getInputData(0);
- var amp = this.properties["amplitude"];
+ var amplitude = this.properties["amplitude"];
+ var slot = this.findInputSlot("amplitude");
+ if(slot != -1)
+ amplitude = this.getInputData(slot);
+ var offset = this.properties["offset"];
+ slot = this.findInputSlot("offset");
+ if(slot != -1)
+ offset = this.getInputData(slot);
+
for(var i = 0, l = this.outputs.length; i < l; ++i)
{
var output = this.outputs[i];
@@ -5563,10 +5645,16 @@ MathTrigonometry.prototype.onExecute = function()
case "acos": value = Math.acos(v); break;
case "atan": value = Math.atan(v); break;
}
- this.setOutputData(i, amp * value );
+ this.setOutputData(i, amplitude * value + offset);
}
}
+MathTrigonometry.prototype.onGetInputs = function()
+{
+ return [["v","number"],["amplitude","number"],["offset","number"]];
+}
+
+
MathTrigonometry.prototype.onGetOutputs = function()
{
return [["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos","number"],["atan","number"]];
@@ -5656,6 +5744,7 @@ if(window.glMatrix)
{
this.addInputs([["x","number"],["y","number"],["z","number"]]);
this.addOutput("vec3","vec3");
+ this.properties = {x:0, y:0, z:0};
}
Math3DXYZToVec3.title = "XYZ->Vec3";
@@ -5664,11 +5753,11 @@ if(window.glMatrix)
Math3DXYZToVec3.prototype.onExecute = function()
{
var x = this.getInputData(0);
- if(x == null) x = 0;
+ if(x == null) x = this.properties.x;
var y = this.getInputData(1);
- if(y == null) y = 0;
+ if(y == null) y = this.properties.y;
var z = this.getInputData(2);
- if(z == null) z = 0;
+ if(z == null) z = this.properties.z;
this.setOutputData( 0, vec3.fromValues(x,y,z) );
}
diff --git a/build/litegraph.min.js b/build/litegraph.min.js
index ac9f88f3e..a35839456 100644
--- a/build/litegraph.min.js
+++ b/build/litegraph.min.js
@@ -10,8 +10,8 @@ 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=LiteGraph.getTime();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();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;b../src/litegraph.js:299
+ Defined in: ../src/litegraph.js:227
../src/litegraph.js:299
+ ../src/litegraph.js:227
../src/litegraph.js:645
+ ../src/litegraph.js:582
@@ -494,7 +494,7 @@
- ../src/litegraph.js:361
+ ../src/litegraph.js:296
@@ -572,7 +572,7 @@
- ../src/litegraph.js:317
+ ../src/litegraph.js:251
@@ -637,7 +637,7 @@
- ../src/litegraph.js:920
+ ../src/litegraph.js:922
@@ -726,7 +726,7 @@
- ../src/litegraph.js:380
+ ../src/litegraph.js:315
@@ -818,7 +818,7 @@
- ../src/litegraph.js:780
+ ../src/litegraph.js:726
@@ -925,7 +925,7 @@
- ../src/litegraph.js:764
+ ../src/litegraph.js:710
@@ -1022,7 +1022,7 @@
- ../src/litegraph.js:605
+ ../src/litegraph.js:542
@@ -1096,7 +1096,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:594
+ ../src/litegraph.js:531
@@ -1175,7 +1175,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:751
+ ../src/litegraph.js:697
@@ -1279,7 +1279,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:796
+ ../src/litegraph.js:742
@@ -1408,7 +1408,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:583
+ ../src/litegraph.js:520
@@ -1477,7 +1477,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:869
+ ../src/litegraph.js:856
@@ -1542,7 +1542,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:690
+ ../src/litegraph.js:631
@@ -1631,7 +1631,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:443
+ ../src/litegraph.js:378
@@ -1726,7 +1726,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:617
+ ../src/litegraph.js:554
@@ -1825,7 +1825,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:893
+ ../src/litegraph.js:889
@@ -1910,7 +1910,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:817
+ ../src/litegraph.js:804
@@ -2020,7 +2020,7 @@ can be easily accesed from the outside of the graph
- ../src/litegraph.js:832
+ ../src/litegraph.js:819
@@ -2123,7 +2123,7 @@ can be easily accesed from the outside of the graph
- ../src/litegraph.js:394
+ ../src/litegraph.js:329
@@ -2202,7 +2202,7 @@ can be easily accesed from the outside of the graph
- ../src/litegraph.js:421
+ ../src/litegraph.js:356
@@ -2257,7 +2257,7 @@ can be easily accesed from the outside of the graph
- ../src/litegraph.js:487
+ ../src/litegraph.js:422
diff --git a/doc/classes/LGraphCanvas.html b/doc/classes/LGraphCanvas.html
index fcb197b6b..2d66a2b02 100644
--- a/doc/classes/LGraphCanvas.html
+++ b/doc/classes/LGraphCanvas.html
@@ -96,7 +96,7 @@
../src/litegraph.js:1794
+ Defined in: ../src/litegraph.js:2116
The Global Scope. It contains all the registered node classes.
+marks as dirty the canvas, this way it will be rendered again
../src/litegraph.js:1794
+ ../src/litegraph.js:2116
@@ -192,7 +192,7 @@
the canvas where you want to render (it accepts a selector in string format)
+the canvas where you want to render (it accepts a selector in string format or the canvas itself)
[optional]
+clearclears all the data inside
+ +getCanvasWindowUsed to attach the canvas in a popup
+ +returns the window where the canvas is attached (the DOM root node)
+ + +setCanvasassigns
+
+ assigns a canvas
+ +assigns
+ Canvas
+
+
+
+
+ a canvas
+ +setGraphassigns
+
+ assigns a graph, you can reasign graphs to the same canvas
+ +assigns
+ LGraph
+
+
+
+
+ a graph
+ +startRenderingstarts rendering the content of the canvas when needed
+ +stopRenderingstops rendering the content of the canvas (to save resources)
+ +../src/litegraph.js:997
+ Defined in: ../src/litegraph.js:1000
../src/litegraph.js:1320
+ ../src/litegraph.js:1385
@@ -528,7 +563,7 @@
- ../src/litegraph.js:1289
+ ../src/litegraph.js:1331
@@ -603,6 +638,95 @@
+
+
+
+ addInputsarray
+
+ add several new input slots in this node
+ +array
+ Array
+
+
+
+
+ of triplets like [[name,type,extra_info],[...]]
+ +../src/litegraph.js:1258
+ ../src/litegraph.js:1277
@@ -735,6 +859,95 @@
+
+
+
+ addOutputsarray
+
+ add a new output slot to use in this node
+ +array
+ Array
+
+
+
+
+ of triplets like [[name,type,extra_info],[...]]
+ +../src/litegraph.js:1756
+ ../src/litegraph.js:1842
@@ -839,7 +1052,7 @@
- ../src/litegraph.js:1333
+ ../src/litegraph.js:1398
@@ -931,7 +1144,7 @@
- ../src/litegraph.js:1026
+ ../src/litegraph.js:1029
@@ -942,7 +1155,7 @@
configure a node from an object
+configure a node from an object containing the serialized info
../src/litegraph.js:1401
+ ../src/litegraph.js:1478
@@ -1151,7 +1364,7 @@
- ../src/litegraph.js:1545
+ ../src/litegraph.js:1628
@@ -1264,7 +1477,7 @@
- ../src/litegraph.js:1482
+ ../src/litegraph.js:1561
@@ -1338,6 +1551,220 @@
+
+
+
+ findInputSlotname
+
+ returns the input slot with a given name (used for dynamic slots), -1 if not found
+ +name
+ String
+
+
+
+
+ the name of the slot
+ +the slot (-1 if not found)
+ + +findOutputSlotname
+
+ returns the output slot with a given name (used for dynamic slots), -1 if not found
+ +name
+ String
+
+
+
+
+ the name of the slot
+ +the slot (-1 if not found)
+ + +../src/litegraph.js:1351
+ ../src/litegraph.js:1416
@@ -1466,7 +1893,7 @@
- ../src/litegraph.js:1599
+ ../src/litegraph.js:1685
@@ -1589,7 +2016,7 @@
- ../src/litegraph.js:1161
+ ../src/litegraph.js:1180
@@ -1695,7 +2122,7 @@
- ../src/litegraph.js:1187
+ ../src/litegraph.js:1206
@@ -1799,7 +2226,7 @@
- ../src/litegraph.js:1202
+ ../src/litegraph.js:1221
@@ -1903,7 +2330,7 @@
- ../src/litegraph.js:1229
+ ../src/litegraph.js:1248
@@ -1958,6 +2385,61 @@
+
+
+
+ getTitleget the title string
+ +../src/litegraph.js:1175
+ ../src/litegraph.js:1194
@@ -2111,7 +2593,7 @@
- ../src/litegraph.js:1217
+ ../src/litegraph.js:1236
@@ -2221,7 +2703,7 @@
- ../src/litegraph.js:1361
+ ../src/litegraph.js:1426
@@ -2326,7 +2808,7 @@
- ../src/litegraph.js:1769
+ ../src/litegraph.js:1855
@@ -2391,7 +2873,7 @@
- ../src/litegraph.js:1308
+ ../src/litegraph.js:1373
@@ -2479,7 +2961,7 @@
- ../src/litegraph.js:1277
+ ../src/litegraph.js:1319
@@ -2557,7 +3039,7 @@
- ../src/litegraph.js:1073
+ ../src/litegraph.js:1075
@@ -2628,7 +3110,7 @@
- ../src/litegraph.js:1145
+ ../src/litegraph.js:1161
@@ -2721,7 +3203,7 @@
- ../src/litegraph.js:1132
+ ../src/litegraph.js:1136
diff --git a/doc/classes/LiteGraph.html b/doc/classes/LiteGraph.html
index e2709b8d7..9cab56904 100644
--- a/doc/classes/LiteGraph.html
+++ b/doc/classes/LiteGraph.html
@@ -298,7 +298,7 @@
- ../src/litegraph.js:67
+ ../src/litegraph.js:65
@@ -423,7 +423,7 @@
- ../src/litegraph.js:143
+ ../src/litegraph.js:105
@@ -530,7 +530,7 @@
- ../src/litegraph.js:156
+ ../src/litegraph.js:118
@@ -627,7 +627,7 @@
- ../src/litegraph.js:178
+ ../src/litegraph.js:140
@@ -712,7 +712,7 @@
- ../src/litegraph.js:33
+ ../src/litegraph.js:34
diff --git a/doc/data.json b/doc/data.json
index ca7f52bba..4e51b636d 100644
--- a/doc/data.json
+++ b/doc/data.json
@@ -38,7 +38,7 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
- "line": 299,
+ "line": 227,
"description": "LGraph is the class that contain a full graph. We instantiate one and add nodes to it, and then we can run the execution loop.",
"is_constructor": 1
},
@@ -51,7 +51,7 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
- "line": 997,
+ "line": 1000,
"description": "Base Class for all the node type classes",
"params": [
{
@@ -70,27 +70,28 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
- "line": 1794,
- "description": "The Global Scope. It contains all the registered node classes.",
+ "line": 2116,
+ "description": "marks as dirty the canvas, this way it will be rendered again",
"is_constructor": 1,
"params": [
{
"name": "canvas",
- "description": "the canvas where you want to render (it accepts a selector in string format)",
+ "description": "the canvas where you want to render (it accepts a selector in string format or the canvas itself)",
"type": "HTMLCanvas"
},
{
"name": "graph",
- "description": "",
+ "description": "[optional]",
"type": "LGraph"
}
- ]
+ ],
+ "itemtype": "method"
}
},
"classitems": [
{
"file": "../src/litegraph.js",
- "line": 33,
+ "line": 34,
"description": "Register a node class so it can be listed when the user wants to create a new one",
"itemtype": "method",
"name": "registerNodeType",
@@ -110,7 +111,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 67,
+ "line": 65,
"description": "Create a node of a given type with a name. The node is not attached to any graph yet.",
"itemtype": "method",
"name": "createNode",
@@ -135,7 +136,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 143,
+ "line": 105,
"description": "Returns a registered node type with a given name",
"itemtype": "method",
"name": "getNodeType",
@@ -154,7 +155,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 156,
+ "line": 118,
"description": "Returns a list of node types matching one category",
"itemtype": "method",
"name": "getNodeType",
@@ -173,7 +174,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 178,
+ "line": 140,
"description": "Returns a list with all the node type categories",
"itemtype": "method",
"name": "getNodeTypesCategories",
@@ -185,7 +186,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 317,
+ "line": 251,
"description": "Removes all nodes from this graph",
"itemtype": "method",
"name": "clear",
@@ -193,7 +194,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 361,
+ "line": 296,
"description": "Attach Canvas to this graph",
"itemtype": "method",
"name": "attachCanvas",
@@ -208,7 +209,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 380,
+ "line": 315,
"description": "Detach Canvas from this graph",
"itemtype": "method",
"name": "detachCanvas",
@@ -223,7 +224,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 394,
+ "line": 329,
"description": "Starts running this graph every interval milliseconds.",
"itemtype": "method",
"name": "start",
@@ -238,7 +239,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 421,
+ "line": 356,
"description": "Stops the execution loop of the graph",
"itemtype": "method",
"name": "stop execution",
@@ -246,7 +247,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 443,
+ "line": 378,
"description": "Run N steps (cycles) of the graph",
"itemtype": "method",
"name": "runStep",
@@ -261,7 +262,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 487,
+ "line": 422,
"description": "Updates the graph execution order according to relevance of the nodes (nodes with only outputs have more relevance than\nnodes with only inputs.",
"itemtype": "method",
"name": "updateExecutionOrder",
@@ -269,7 +270,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 583,
+ "line": 520,
"description": "Returns the amount of time the graph has been running in milliseconds",
"itemtype": "method",
"name": "getTime",
@@ -281,7 +282,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 594,
+ "line": 531,
"description": "Returns the amount of time accumulated using the fixedtime_lapse var. This is used in context where the time increments should be constant",
"itemtype": "method",
"name": "getFixedTime",
@@ -293,7 +294,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 605,
+ "line": 542,
"description": "Returns the amount of time it took to compute the latest iteration. Take into account that this number could be not correct\nif the nodes are using graphical actions",
"itemtype": "method",
"name": "getElapsedTime",
@@ -305,7 +306,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 617,
+ "line": 554,
"description": "Sends an event to all the nodes, useful to trigger stuff",
"itemtype": "method",
"name": "sendEventToAllNodes",
@@ -325,7 +326,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 645,
+ "line": 582,
"description": "Adds a new node instasnce to this graph",
"itemtype": "method",
"name": "add",
@@ -340,7 +341,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 690,
+ "line": 631,
"description": "Removes a node from the graph",
"itemtype": "method",
"name": "remove",
@@ -355,7 +356,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 751,
+ "line": 697,
"description": "Returns a node by its id.",
"itemtype": "method",
"name": "getNodeById",
@@ -370,7 +371,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 764,
+ "line": 710,
"description": "Returns a list of nodes that matches a type",
"itemtype": "method",
"name": "findNodesByType",
@@ -389,7 +390,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 780,
+ "line": 726,
"description": "Returns a list of nodes that matches a name",
"itemtype": "method",
"name": "findNodesByName",
@@ -408,7 +409,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 796,
+ "line": 742,
"description": "Returns the top-most node in this position of the canvas",
"itemtype": "method",
"name": "getNodeOnPos",
@@ -437,7 +438,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 817,
+ "line": 804,
"description": "Assigns a value to all the nodes that matches this name. This is used to create global variables of the node that\ncan be easily accesed from the outside of the graph",
"itemtype": "method",
"name": "setInputData",
@@ -457,7 +458,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 832,
+ "line": 819,
"description": "Returns the value of the first node with this name. This is used to access global variables of the graph from the outside",
"itemtype": "method",
"name": "setInputData",
@@ -476,7 +477,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 869,
+ "line": 856,
"description": "returns if the graph is in live mode",
"itemtype": "method",
"name": "isLive",
@@ -484,7 +485,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 893,
+ "line": 889,
"description": "Creates a Object containing all the info about this graph, it can be serialized",
"itemtype": "method",
"name": "serialize",
@@ -496,7 +497,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 920,
+ "line": 922,
"description": "Configure a graph from a JSON string",
"itemtype": "method",
"name": "configure",
@@ -511,15 +512,15 @@
},
{
"file": "../src/litegraph.js",
- "line": 1026,
- "description": "configure a node from an object",
+ "line": 1029,
+ "description": "configure a node from an object containing the serialized info",
"itemtype": "method",
"name": "configure",
"class": "LGraphNode"
},
{
"file": "../src/litegraph.js",
- "line": 1073,
+ "line": 1075,
"description": "serialize the content",
"itemtype": "method",
"name": "serialize",
@@ -527,7 +528,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1132,
+ "line": 1136,
"description": "serialize and stringify",
"itemtype": "method",
"name": "toString",
@@ -535,7 +536,15 @@
},
{
"file": "../src/litegraph.js",
- "line": 1145,
+ "line": 1148,
+ "description": "get the title string",
+ "itemtype": "method",
+ "name": "getTitle",
+ "class": "LGraphNode"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1161,
"description": "sets the output data",
"itemtype": "method",
"name": "setOutputData",
@@ -555,7 +564,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1161,
+ "line": 1180,
"description": "retrieves the input data from one slot",
"itemtype": "method",
"name": "getInputData",
@@ -574,7 +583,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1175,
+ "line": 1194,
"description": "tells you if there is a connection in one input slot",
"itemtype": "method",
"name": "isInputConnected",
@@ -593,7 +602,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1187,
+ "line": 1206,
"description": "tells you info about an input connection (which node, type, etc)",
"itemtype": "method",
"name": "getInputInfo",
@@ -612,7 +621,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1202,
+ "line": 1221,
"description": "tells you info about an output connection (which node, type, etc)",
"itemtype": "method",
"name": "getOutputInfo",
@@ -631,7 +640,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1217,
+ "line": 1236,
"description": "tells you if there is a connection in one output slot",
"itemtype": "method",
"name": "isOutputConnected",
@@ -650,7 +659,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1229,
+ "line": 1248,
"description": "retrieves all the nodes connected to this output slot",
"itemtype": "method",
"name": "getOutputNodes",
@@ -669,7 +678,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1258,
+ "line": 1277,
"description": "add a new output slot to use in this node",
"itemtype": "method",
"name": "addOutput",
@@ -694,7 +703,22 @@
},
{
"file": "../src/litegraph.js",
- "line": 1277,
+ "line": 1296,
+ "description": "add a new output slot to use in this node",
+ "itemtype": "method",
+ "name": "addOutputs",
+ "params": [
+ {
+ "name": "array",
+ "description": "of triplets like [[name,type,extra_info],[...]]",
+ "type": "Array"
+ }
+ ],
+ "class": "LGraphNode"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1319,
"description": "remove an existing output slot",
"itemtype": "method",
"name": "removeOutput",
@@ -709,7 +733,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1289,
+ "line": 1331,
"description": "add a new input slot to use in this node",
"itemtype": "method",
"name": "addInput",
@@ -734,7 +758,22 @@
},
{
"file": "../src/litegraph.js",
- "line": 1308,
+ "line": 1350,
+ "description": "add several new input slots in this node",
+ "itemtype": "method",
+ "name": "addInputs",
+ "params": [
+ {
+ "name": "array",
+ "description": "of triplets like [[name,type,extra_info],[...]]",
+ "type": "Array"
+ }
+ ],
+ "class": "LGraphNode"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1373,
"description": "remove an existing input slot",
"itemtype": "method",
"name": "removeInput",
@@ -749,7 +788,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1320,
+ "line": 1385,
"description": "add an special connection to this node (used for special kinds of graphs)",
"itemtype": "method",
"name": "addConnection",
@@ -779,7 +818,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1333,
+ "line": 1398,
"description": "computes the size of a node according to its inputs and output slots",
"itemtype": "method",
"name": "computeSize",
@@ -798,7 +837,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1351,
+ "line": 1416,
"description": "returns the bounding of the object, used for rendering purposes",
"itemtype": "method",
"name": "getBounding",
@@ -810,7 +849,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1361,
+ "line": 1426,
"description": "checks if a point is inside the shape of a node",
"itemtype": "method",
"name": "isPointInsideNode",
@@ -834,7 +873,45 @@
},
{
"file": "../src/litegraph.js",
- "line": 1401,
+ "line": 1448,
+ "description": "returns the input slot with a given name (used for dynamic slots), -1 if not found",
+ "itemtype": "method",
+ "name": "findInputSlot",
+ "params": [
+ {
+ "name": "name",
+ "description": "the name of the slot",
+ "type": "String"
+ }
+ ],
+ "return": {
+ "description": "the slot (-1 if not found)",
+ "type": "Number"
+ },
+ "class": "LGraphNode"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1463,
+ "description": "returns the output slot with a given name (used for dynamic slots), -1 if not found",
+ "itemtype": "method",
+ "name": "findOutputSlot",
+ "params": [
+ {
+ "name": "name",
+ "description": "the name of the slot",
+ "type": "String"
+ }
+ ],
+ "return": {
+ "description": "the slot (-1 if not found)",
+ "type": "Number"
+ },
+ "class": "LGraphNode"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1478,
"description": "connect this node output to the input of another node",
"itemtype": "method",
"name": "connect",
@@ -863,7 +940,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1482,
+ "line": 1561,
"description": "disconnect one output to an specific node",
"itemtype": "method",
"name": "disconnectOutput",
@@ -887,7 +964,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1545,
+ "line": 1628,
"description": "disconnect one input",
"itemtype": "method",
"name": "disconnectInput",
@@ -906,7 +983,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1599,
+ "line": 1685,
"description": "returns the center of a connection point in canvas coords",
"itemtype": "method",
"name": "getConnectionPos",
@@ -930,7 +1007,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1756,
+ "line": 1842,
"description": "Collapse the node to make it smaller on the canvas",
"itemtype": "method",
"name": "collapse",
@@ -938,11 +1015,77 @@
},
{
"file": "../src/litegraph.js",
- "line": 1769,
+ "line": 1855,
"description": "Forces the node to do not move or realign on Z",
"itemtype": "method",
"name": "pin",
"class": "LGraphNode"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1912,
+ "description": "clears all the data inside",
+ "itemtype": "method",
+ "name": "clear",
+ "class": "LGraphCanvas"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1966,
+ "description": "assigns a graph, you can reasign graphs to the same canvas",
+ "itemtype": "method",
+ "name": "setGraph",
+ "params": [
+ {
+ "name": "assigns",
+ "description": "a graph",
+ "type": "LGraph"
+ }
+ ],
+ "class": "LGraphCanvas"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 1994,
+ "description": "assigns a canvas",
+ "itemtype": "method",
+ "name": "setCanvas",
+ "params": [
+ {
+ "name": "assigns",
+ "description": "a canvas",
+ "type": "Canvas"
+ }
+ ],
+ "class": "LGraphCanvas"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 2132,
+ "description": "Used to attach the canvas in a popup",
+ "itemtype": "method",
+ "name": "getCanvasWindow",
+ "return": {
+ "description": "returns the window where the canvas is attached (the DOM root node)",
+ "type": "Window"
+ },
+ "class": "LGraphCanvas"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 2144,
+ "description": "starts rendering the content of the canvas when needed",
+ "itemtype": "method",
+ "name": "startRendering",
+ "class": "LGraphCanvas"
+ },
+ {
+ "file": "../src/litegraph.js",
+ "line": 2175,
+ "description": "stops rendering the content of the canvas (to save resources)",
+ "itemtype": "method",
+ "name": "stopRendering",
+ "class": "LGraphCanvas"
}
],
"warnings": []
diff --git a/doc/files/.._src_litegraph.js.html b/doc/files/.._src_litegraph.js.html
index 50a66387c..7c64f139b 100644
--- a/doc/files/.._src_litegraph.js.html
+++ b/doc/files/.._src_litegraph.js.html
@@ -118,10 +118,11 @@ 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,
+ throw_errors: true,
registered_node_types: {},
/**
@@ -133,13 +134,10 @@ var LiteGraph = {
registerNodeType: function(type, base_class)
{
- var title = type;
- if(base_class.prototype && base_class.prototype.title)
- title = base_class.prototype.title;
- else if(base_class.title)
- title = base_class.title;
-
+ if(!base_class.prototype)
+ throw("Cannot register a simple object, it must be a class with a prototype");
base_class.type = type;
+
if(LiteGraph.debug)
console.log("Node registered: " + type);
@@ -149,13 +147,13 @@ var LiteGraph = {
base_class.category = type.substr(0,pos);
//info.name = name.substr(pos+1,name.length - pos);
- //inheritance
+ //extend class
if(base_class.prototype) //is a class
for(var i in LGraphNode.prototype)
if(!base_class.prototype[i])
base_class.prototype[i] = LGraphNode.prototype[i];
- this.registered_node_types[type] = base_class;
+ this.registered_node_types[ type ] = base_class;
},
/**
@@ -166,7 +164,7 @@ var LiteGraph = {
* @param {Object} options to set options
*/
- createNode: function(type,name, options)
+ createNode: function(type, title, options)
{
var base_class = this.registered_node_types[type];
if (!base_class)
@@ -178,48 +176,12 @@ var LiteGraph = {
var prototype = base_class.prototype || base_class;
- name = name || prototype.title || base_class.title || type;
+ title = title || base_class.title || type;
- var node = null;
- 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
- }
+ var node = new base_class( name );
node.type = type;
- if(!node.name) node.name = name;
+ if(!node.title) node.title = title;
if(!node.flags) node.flags = {};
if(!node.size) node.size = node.computeSize();
if(!node.pos) node.pos = LiteGraph.DEFAULT_POSITION.concat();
@@ -332,6 +294,7 @@ var LiteGraph = {
//separated just to improve if it doesnt work
cloneObject: function(obj, target)
{
+ if(obj == null) return null;
var r = JSON.parse( JSON.stringify( obj ) );
if(!target) return r;
@@ -339,53 +302,18 @@ var LiteGraph = {
target[i] = r[i];
return target;
}
-
- /*
- benchmark: function(mode)
- {
- mode = mode || "all";
-
- trace("Benchmarking " + mode + "...");
- trace(" Num. nodes: " + this._nodes.length );
- var links = 0;
- for(var i in this._nodes)
- for(var j in this._nodes[i].outputs)
- if(this._nodes[i].outputs[j].node_id != null)
- links++;
- trace(" Num. links: " + links );
-
- var numTimes = 200;
- if(mode == "core")
- numTimes = 30000;
-
- var start = new Date().getTime();
-
- for(var i = 0; i < numTimes; i++)
- {
- if(mode == "render")
- this.draw(false);
- else if(mode == "core")
- this.sendEventToAllNodes("onExecute");
- else
- {
- this.sendEventToAllNodes("onExecute");
- this.draw(false);
- }
- }
-
- var elapsed = (new Date().getTime()) - start;
- trace(" Time take for " + numTimes + " iterations: " + (elapsed*0.001).toFixed(3) + " seconds.");
- var seconds_per_iteration = (elapsed*0.001)/numTimes;
- trace(" Time per iteration: " + seconds_per_iteration.toFixed( seconds_per_iteration < 0.001 ? 6 : 3) + " seconds");
- trace(" Avg FPS: " + (1000/(elapsed/numTimes)).toFixed(3));
- }
- */
};
+if(typeof(performance) != "undefined")
+ LiteGraph.getTime = function getTime() { return performance.now(); }
+else
+ LiteGraph.getTime = function getTime() { return Date.now(); }
+
+
//*********************************************************************************
// LGraph CLASS
//*********************************************************************************
@@ -405,6 +333,12 @@ function LGraph()
this.clear();
}
+//default supported types
+LGraph.supported_types = ["number","string","boolean"];
+
+//used to know which types of connections support this graph (some graphs do not allow certain types)
+LGraph.prototype.getSupportedTypes = function() { return this.supported_types || LGraph.supported_types; }
+
LGraph.STATUS_STOPPED = 1;
LGraph.STATUS_RUNNING = 2;
@@ -425,7 +359,7 @@ LGraph.prototype.clear = function()
//links
this.last_link_id = 0;
- this.links = {};
+ this.links = {}; //container with all the links
//iterations
this.iteration = 0;
@@ -442,7 +376,8 @@ LGraph.prototype.clear = function()
this.starttime = 0;
//globals
- this.globals = {};
+ this.global_inputs = {};
+ this.global_outputs = {};
this.graph = {};
this.debug = true;
@@ -502,7 +437,7 @@ LGraph.prototype.start = function(interval)
this.sendEventToAllNodes("onStart");
//launch
- this.starttime = window.performance.now();
+ this.starttime = LiteGraph.getTime();
interval = interval || 1;
var that = this;
@@ -544,7 +479,7 @@ LGraph.prototype.runStep = function(num)
{
num = num || 1;
- var start = window.performance.now();
+ var start = LiteGraph.getTime();
this.globaltime = 0.001 * (start - this.starttime);
try
@@ -571,7 +506,7 @@ LGraph.prototype.runStep = function(num)
this.stop();
}
- var elapsed = window.performance.now() - start;
+ var elapsed = LiteGraph.getTime() - start;
if (elapsed == 0) elapsed = 1;
this.elapsed_time = 0.001 * elapsed;
this.globaltime += 0.001 * elapsed;
@@ -638,20 +573,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
@@ -742,7 +679,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
@@ -765,16 +702,20 @@ LGraph.prototype.add = function(node)
node.bgImage = node.loadImage(node.bgImageUrl);
*/
- if(node.onInit)
- node.onInit();
+ if(node.onAdded)
+ node.onAdded();
if(this.config.align_to_grid)
node.alignToGrid();
-
- this.updateExecutionOrder();
- if(this.canvas)
- this.canvas.dirty_canvas = true;
+ if(!skip_compute_order)
+ this.updateExecutionOrder();
+
+ if(this.onNodeAdded)
+ this.onNodeAdded(node);
+
+
+ this.setDirtyCanvas(true);
this.change();
@@ -816,16 +757,19 @@ LGraph.prototype.remove = function(node)
node.id = -1;
//callback
- if(node.onDelete)
- node.onDelete();
+ if(node.onRemoved)
+ node.onRemoved();
- //remove from environment
- if(this.canvas)
+ node.graph = null;
+
+ //remove from canvas render
+ for(var i in this.list_of_graphcanvas)
{
- if(this.canvas.selected_nodes[node.id])
- delete this.canvas.selected_nodes[node.id];
- if(this.canvas.node_dragged == node)
- this.canvas.node_dragged = null;
+ 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
@@ -834,8 +778,10 @@ LGraph.prototype.remove = function(node)
this._nodes.splice(pos,1);
delete this._nodes_by_id[node.id];
- if(this.canvas)
- this.canvas.setDirty(true,true);
+ if(this.onNodeRemoved)
+ this.onNodeRemoved(node);
+
+ this.setDirtyCanvas(true,true);
this.change();
@@ -878,11 +824,11 @@ LGraph.prototype.findNodesByType = function(type)
* @return {Array} a list with all the nodes with this name
*/
-LGraph.prototype.findNodesByName = function(name)
+LGraph.prototype.findNodesByTitle = function(title)
{
var result = [];
for (var i in this._nodes)
- if(this._nodes[i].name == name)
+ if(this._nodes[i].title == title)
result.push(this._nodes[i]);
return result;
}
@@ -908,6 +854,47 @@ LGraph.prototype.getNodeOnPos = function(x,y, nodes_list)
return null;
}
+//Tell this graph has a global input of this type
+LGraph.prototype.addGlobalInput = function(name, type, value)
+{
+ this.global_inputs[name] = { type: type, value: value };
+}
+
+//assign a data to the global input
+LGraph.prototype.setGlobalInputData = function(name, data)
+{
+ var input = this.global_inputs[name];
+ if (!input)
+ return;
+ input.value = data;
+}
+
+//rename the global input
+LGraph.prototype.renameGlobalInput = function(old_name, name, data)
+{
+}
+
+
+LGraph.prototype.addGlobalOutput = function(name, type, value)
+{
+ this.global_outputs[name] = { type: type, value: value };
+}
+
+//assign a data to the global output
+LGraph.prototype.setGlobalOutputData = function(name, data)
+{
+ var output = this.global_outputs[ name ];
+ if (!output)
+ return;
+ output.value = data;
+}
+
+//rename the global output
+LGraph.prototype.renameGlobalOutput = function(old_name, name, data)
+{
+}
+
+
/**
* Assigns a value to all the nodes that matches this name. This is used to create global variables of the node that
* can be easily accesed from the outside of the graph
@@ -967,8 +954,12 @@ LGraph.prototype.onConnectionChange = function()
LGraph.prototype.isLive = function()
{
- if(!this.canvas) return false;
- return this.canvas.live_mode;
+ for(var i in this.list_of_graphcanvas)
+ {
+ var c = this.list_of_graphcanvas[i];
+ if(c.live_mode) return true;
+ }
+ return false;
}
/* Called when something visually changed */
@@ -983,6 +974,11 @@ LGraph.prototype.change = function()
this.on_change(this);
}
+LGraph.prototype.setDirtyCanvas = function(fg,bg)
+{
+ this.sendActionToCanvas("setDirty",[fg,bg]);
+}
+
//save and recover app state ***************************************
/**
* Creates a Object containing all the info about this graph, it can be serialized
@@ -995,6 +991,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,
@@ -1002,6 +1003,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
@@ -1034,8 +1036,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.name );
- 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);
@@ -1043,21 +1045,19 @@ 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);
}
- //TODO: dispatch redraw
- if(this.canvas)
- this.canvas.draw(true,true);
-
+ this.updateExecutionOrder();
+ this.setDirtyCanvas(true,true);
return error;
}
LGraph.prototype.onNodeTrace = function(node, msg, color)
{
- if(this.canvas)
- this.canvas.onNodeTrace(node,msg,color);
+ //TODO
}
// *************************************************************
@@ -1070,18 +1070,21 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
+ unsafe_execution: not allowed for safe execution
supported callbacks:
- + onInit: when added to graph
+ + onAdded: when added to graph
+ + onRemoved: when removed from graph
+ onStart: when starts playing
+ onStop: when stops playing
- + onDrawForeground
- + onDrawBackground
+ + onDrawForeground: render the inside widgets inside the node
+ + onDrawBackground: render the background area inside the node (only in edit mode)
+ + onMouseDown
+ onMouseMove
- + onMouseOver
+ + onMouseUp
+ + onMouseEnter
+ + onMouseLeave
+ onExecute: execute the node
+ onPropertyChange: when a property is changed in the panel (return true to skip default behaviour)
+ onGetInputs: returns an array of possible inputs
+ onGetOutputs: returns an array of possible outputs
- + onClick
+ onDblClick
+ onSerialize
+ onSelected
@@ -1094,9 +1097,9 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
* @param {String} name a name for the node
*/
-function LGraphNode(name)
+function LGraphNode(title)
{
- this.name = name || "Unnamed";
+ this.title = title || "Unnamed";
this.size = [LiteGraph.NODE_WIDTH,60];
this.graph = null;
@@ -1118,7 +1121,7 @@ function LGraphNode(name)
}
/**
-* configure a node from an object
+* configure a node from an object containing the serialized info
* @method configure
*/
LGraphNode.prototype.configure = function(info)
@@ -1129,39 +1132,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] || {} );
+ 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];
+ }
+ }
+
}
/**
@@ -1173,17 +1175,19 @@ LGraphNode.prototype.serialize = function()
{
var o = {
id: this.id,
- name: this.name,
+ title: this.title,
type: this.type,
pos: this.pos,
size: this.size,
data: this.data,
- properties: LiteGraph.cloneObject(this.properties),
flags: LiteGraph.cloneObject(this.flags),
inputs: this.inputs,
outputs: this.outputs
};
+ if(this.properties)
+ o.properties = LiteGraph.cloneObject(this.properties);
+
if(!o.type)
o.type = this.constructor.type;
@@ -1210,8 +1214,8 @@ LGraphNode.prototype.reducedObjectivize = function()
var type = LiteGraph.getNodeType(o.type);
- if(type.name == o.name)
- delete o["name"];
+ if(type.title == o.title)
+ delete o["title"];
if(type.size && compareObjects(o.size,type.size))
delete o["size"];
@@ -1235,6 +1239,18 @@ LGraphNode.prototype.toString = function()
//LGraphNode.prototype.unserialize = function(info) {} //this cannot be done from within, must be done in LiteGraph
+/**
+* get the title string
+* @method getTitle
+*/
+
+LGraphNode.prototype.getTitle = function()
+{
+ return this.title || this.constructor.title;
+}
+
+
+
// Execution *************************
/**
* sets the output data
@@ -1248,7 +1264,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;
+ }
}
}
@@ -1262,7 +1281,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;
}
@@ -1334,7 +1353,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;
@@ -1368,6 +1387,29 @@ LGraphNode.prototype.addOutput = function(name,type,extra_info)
this.size = this.computeSize();
}
+/**
+* add a new output slot to use in this node
+* @method addOutputs
+* @param {Array} array of triplets like [[name,type,extra_info],[...]]
+*/
+LGraphNode.prototype.addOutputs = function(array)
+{
+ for(var i in array)
+ {
+ var info = array[i];
+ var o = {name:info[0],type:info[1],link:null};
+ if(array[2])
+ for(var j in info[2])
+ o[j] = info[2][j];
+
+ if(!this.outputs)
+ this.outputs = [];
+ this.outputs.push(o);
+ }
+
+ this.size = this.computeSize();
+}
+
/**
* remove an existing output slot
* @method removeOutput
@@ -1399,6 +1441,29 @@ LGraphNode.prototype.addInput = function(name,type,extra_info)
this.size = this.computeSize();
}
+/**
+* add several new input slots in this node
+* @method addInputs
+* @param {Array} array of triplets like [[name,type,extra_info],[...]]
+*/
+LGraphNode.prototype.addInputs = function(array)
+{
+ for(var i in array)
+ {
+ var info = array[i];
+ var o = {name:info[0],type:info[1],link:null};
+ if(array[2])
+ for(var j in info[2])
+ o[j] = info[2][j];
+
+ if(!this.inputs)
+ this.inputs = [];
+ this.inputs.push(o);
+ }
+
+ this.size = this.computeSize();
+}
+
/**
* remove an existing input slot
* @method removeInput
@@ -1461,7 +1526,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)
@@ -1474,6 +1539,12 @@ LGraphNode.prototype.isPointInsideNode = function(x,y)
return false;
}
+/**
+* returns the input slot with a given name (used for dynamic slots), -1 if not found
+* @method findInputSlot
+* @param {string} name the name of the slot
+* @return {number} the slot (-1 if not found)
+*/
LGraphNode.prototype.findInputSlot = function(name)
{
if(!this.inputs) return -1;
@@ -1483,6 +1554,12 @@ LGraphNode.prototype.findInputSlot = function(name)
return -1;
}
+/**
+* returns the output slot with a given name (used for dynamic slots), -1 if not found
+* @method findOutputSlot
+* @param {string} name the name of the slot
+* @return {number} the slot (-1 if not found)
+*/
LGraphNode.prototype.findOutputSlot = function(name)
{
if(!this.outputs) return -1;
@@ -1560,12 +1637,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();
@@ -1608,13 +1687,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]];
+ 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;
}
}
@@ -1623,10 +1704,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;
}
@@ -1664,21 +1747,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;
@@ -1843,7 +1929,7 @@ LGraphNode.prototype.captureInput = function(v)
//change
c.node_capturing_input = v ? this : null;
if(this.graph.debug)
- console.log(this.name + ": Capturing input " + (v?"ON":"OFF"));
+ console.log(this.title + ": Capturing input " + (v?"ON":"OFF"));
}
}
@@ -1890,8 +1976,8 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas)
*
* @class LGraphCanvas
* @constructor
-* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format)
-* @param {LGraph} graph
+* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format or the canvas itself)
+* @param {LGraph} graph [optional]
*/
function LGraphCanvas(canvas, graph)
{
@@ -1916,6 +2002,12 @@ function LGraphCanvas(canvas, graph)
LGraphCanvas.link_type_colors = {'number':"#AAC",'node':"#DCA"};
+
+/**
+* clears all the data inside
+*
+* @method clear
+*/
LGraphCanvas.prototype.clear = function()
{
this.frame = 0;
@@ -1965,6 +2057,12 @@ LGraphCanvas.prototype.clear = function()
//this.UIinit();
}
+/**
+* assigns a graph, you can reasign graphs to the same canvas
+*
+* @method setGraph
+* @param {LGraph} assigns a graph
+*/
LGraphCanvas.prototype.setGraph = function(graph)
{
if(this.graph == graph) return;
@@ -1987,6 +2085,12 @@ LGraphCanvas.prototype.setGraph = function(graph)
this.setDirty(true,true);
}
+/**
+* assigns a canvas
+*
+* @method setCanvas
+* @param {Canvas} assigns a canvas
+*/
LGraphCanvas.prototype.setCanvas = function(canvas)
{
var that = this;
@@ -2025,7 +2129,7 @@ LGraphCanvas.prototype.setCanvas = function(canvas)
this._mousemove_callback = this.processMouseMove.bind(this);
this._mouseup_callback = this.processMouseUp.bind(this);
- this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this) ); //down do not need to store the binded
+ this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded
this.canvas.addEventListener("mousemove", this._mousemove_callback);
this.canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; });
@@ -2103,6 +2207,14 @@ LGraphCanvas.prototype.UIinit = function()
}
*/
+/**
+* marks as dirty the canvas, this way it will be rendered again
+*
+* @class LGraphCanvas
+* @method setDirty
+* @param {bool} fgcanvas if the foreground canvas is dirty (the one containing the nodes)
+* @param {bool} bgcanvas if the background canvas is dirty (the one containing the wires)
+*/
LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas)
{
if(fgcanvas)
@@ -2111,13 +2223,23 @@ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas)
this.dirty_bgcanvas = true;
}
-//Used to attach the canvas in a popup
+/**
+* Used to attach the canvas in a popup
+*
+* @method getCanvasWindow
+* @return {window} returns the window where the canvas is attached (the DOM root node)
+*/
LGraphCanvas.prototype.getCanvasWindow = function()
{
var doc = this.canvas.ownerDocument;
return doc.defaultView || doc.parentWindow;
}
+/**
+* starts rendering the content of the canvas when needed
+*
+* @method startRendering
+*/
LGraphCanvas.prototype.startRendering = function()
{
if(this.is_rendering) return; //already rendering
@@ -2144,6 +2266,11 @@ LGraphCanvas.prototype.startRendering = function()
*/
}
+/**
+* stops rendering the content of the canvas (to save resources)
+*
+* @method stopRendering
+*/
LGraphCanvas.prototype.stopRendering = function()
{
this.is_rendering = false;
@@ -2168,8 +2295,8 @@ LGraphCanvas.prototype.processMouseDown = function(e)
var document = ref_window.document;
this.canvas.removeEventListener("mousemove", this._mousemove_callback );
- ref_window.document.addEventListener("mousemove", this._mousemove_callback ); //catch for the entire window
- ref_window.document.addEventListener("mouseup", this._mouseup_callback );
+ ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
+ ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
var n = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes);
var skip_dragging = false;
@@ -2250,7 +2377,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
var block_drag_node = false;
//double clicking
- var now = window.performance.now();
+ var now = LiteGraph.getTime();
if ((now - this.last_mouseclick) < 300 && this.selected_nodes[n.id])
{
//double click node
@@ -2305,7 +2432,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
this.last_mouse[0] = e.localX;
this.last_mouse[1] = e.localY;
- this.last_mouseclick = window.performance.now();
+ this.last_mouseclick = LiteGraph.getTime();
this.canvas_mouse = [e.canvasX, e.canvasY];
/*
@@ -2422,8 +2549,8 @@ LGraphCanvas.prototype.processMouseMove = function(e)
n.pos[0] += delta[0] / this.scale;
n.pos[1] += delta[1] / this.scale;
- n.pos[0] = Math.round(n.pos[0]);
- n.pos[1] = Math.round(n.pos[1]);
+ //n.pos[0] = Math.round(n.pos[0]);
+ //n.pos[1] = Math.round(n.pos[1]);
}
this.dirty_canvas = true;
@@ -2516,7 +2643,8 @@ LGraphCanvas.prototype.processMouseUp = function(e)
{
this.dirty_canvas = true;
this.dirty_bgcanvas = true;
-
+ this.node_dragged.pos[0] = Math.round(this.node_dragged.pos[0]);
+ this.node_dragged.pos[1] = Math.round(this.node_dragged.pos[1]);
if(this.graph.config.align_to_grid)
this.node_dragged.alignToGrid();
this.node_dragged = null;
@@ -2856,7 +2984,7 @@ LGraphCanvas.prototype.computeVisibleNodes = function()
LGraphCanvas.prototype.draw = function(force_canvas, force_bgcanvas)
{
//fps counting
- var now = window.performance.now();
+ var now = LiteGraph.getTime();
this.render_time = (now - this.last_draw_time)*0.001;
this.last_draw_time = now;
@@ -3103,10 +3231,10 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
}
else if(this.render_shadows)
{
- ctx.shadowColor = "#111";
+ ctx.shadowColor = "rgba(0,0,0,0.5)";
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
- ctx.shadowBlur = 4;
+ ctx.shadowBlur = 3;
}
else
ctx.shadowColor = "transparent";
@@ -3363,10 +3491,11 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
//title text
ctx.font = this.title_text_font;
- if(node.name != "" && this.scale > 0.8)
+ var title = node.getTitle();
+ if(title && this.scale > 0.8)
{
ctx.fillStyle = "#222";
- ctx.fillText(node.name,16,13-title_height );
+ ctx.fillText( title, 16, 13 - title_height );
}
}
}
@@ -3444,12 +3573,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)
@@ -3479,7 +3611,7 @@ LGraphCanvas.prototype.renderLink = function(ctx,a,b,color)
var dist = distance(a,b);
- if(this.render_connections_border)
+ if(this.render_connections_border && this.scale > 0.6)
ctx.lineWidth = this.connections_width + 4;
ctx.beginPath();
@@ -3499,7 +3631,7 @@ LGraphCanvas.prototype.renderLink = function(ctx,a,b,color)
ctx.lineTo(b[0]-10,b[1]);
}
- if(this.render_connections_border)
+ if(this.render_connections_border && this.scale > 0.6)
{
ctx.strokeStyle = "rgba(0,0,0,0.5)";
ctx.stroke();
@@ -3782,7 +3914,7 @@ LGraphCanvas.onMenuNodeOutputs = function(node, e, prev_menu)
LGraphCanvas.onMenuNodeCollapse = function(node)
{
node.flags.collapsed = !node.flags.collapsed;
- node.graph.canvas.setDirty(true,true);
+ node.setDirtyCanvas(true,true);
}
LGraphCanvas.onMenuNodePin = function(node)
@@ -3809,7 +3941,7 @@ LGraphCanvas.onMenuNodeColors = function(node, e, prev_menu)
{
node.color = color.color;
node.bgcolor = color.bgcolor;
- node.graph.canvas.setDirty(true);
+ node.setDirtyCanvas(true);
}
}
@@ -3824,7 +3956,7 @@ LGraphCanvas.onMenuNodeShapes = function(node,e)
{
if(!node) return;
node.shape = v;
- node.graph.canvas.setDirty(true);
+ node.setDirtyCanvas(true);
}
return false;
@@ -3834,7 +3966,7 @@ LGraphCanvas.onMenuNodeRemove = function(node)
{
if(node.removable == false) return;
node.graph.remove(node);
- node.graph.canvas.setDirty(true,true);
+ node.setDirtyCanvas(true,true);
}
LGraphCanvas.onMenuNodeClone = function(node)
@@ -3844,7 +3976,7 @@ LGraphCanvas.onMenuNodeClone = function(node)
if(!newnode) return;
newnode.pos = [node.pos[0]+5,node.pos[1]+5];
node.graph.add(newnode);
- node.graph.canvas.setDirty(true,true);
+ node.setDirtyCanvas(true,true);
}
LGraphCanvas.node_colors = {
@@ -3883,10 +4015,19 @@ LGraphCanvas.prototype.getNodeMenuOptions = function(node)
if( node.removable == false )
options[9].disabled = true;
- if(node.onGetInputs && node.onGetInputs().length )
- options[0].disabled = false;
- if(node.onGetOutputs && node.onGetOutputs().length )
- options[1].disabled = false;
+ if(node.onGetInputs)
+ {
+ var inputs = node.onGetInputs();
+ if(inputs && inputs.length)
+ options[0].disabled = false;
+ }
+
+ if(node.onGetOutputs)
+ {
+ var outputs = node.onGetOutputs();
+ if(outputs && outputs.length )
+ options[1].disabled = false;
+ }
return options;
}
diff --git a/index.html b/index.html
index 6e8b2adef..2ac0f7556 100644
--- a/index.html
+++ b/index.html
@@ -44,6 +44,7 @@
Here you can check automatically generated documentation.
diff --git a/src/litegraph.js b/src/litegraph.js index 77361ed50..02083227c 100644 --- a/src/litegraph.js +++ b/src/litegraph.js @@ -1445,6 +1445,12 @@ LGraphNode.prototype.isPointInsideNode = function(x,y) return false; } +/** +* returns the input slot with a given name (used for dynamic slots), -1 if not found +* @method findInputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findInputSlot = function(name) { if(!this.inputs) return -1; @@ -1454,6 +1460,12 @@ LGraphNode.prototype.findInputSlot = function(name) return -1; } +/** +* returns the output slot with a given name (used for dynamic slots), -1 if not found +* @method findOutputSlot +* @param {string} name the name of the slot +* @return {number} the slot (-1 if not found) +*/ LGraphNode.prototype.findOutputSlot = function(name) { if(!this.outputs) return -1; @@ -1870,8 +1882,8 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas) * * @class LGraphCanvas * @constructor -* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format) -* @param {LGraph} graph +* @param {HTMLCanvas} canvas the canvas where you want to render (it accepts a selector in string format or the canvas itself) +* @param {LGraph} graph [optional] */ function LGraphCanvas(canvas, graph) { @@ -1896,6 +1908,12 @@ function LGraphCanvas(canvas, graph) LGraphCanvas.link_type_colors = {'number':"#AAC",'node':"#DCA"}; + +/** +* clears all the data inside +* +* @method clear +*/ LGraphCanvas.prototype.clear = function() { this.frame = 0; @@ -1945,6 +1963,12 @@ LGraphCanvas.prototype.clear = function() //this.UIinit(); } +/** +* assigns a graph, you can reasign graphs to the same canvas +* +* @method setGraph +* @param {LGraph} assigns a graph +*/ LGraphCanvas.prototype.setGraph = function(graph) { if(this.graph == graph) return; @@ -1967,6 +1991,12 @@ LGraphCanvas.prototype.setGraph = function(graph) this.setDirty(true,true); } +/** +* assigns a canvas +* +* @method setCanvas +* @param {Canvas} assigns a canvas +*/ LGraphCanvas.prototype.setCanvas = function(canvas) { var that = this; @@ -2005,7 +2035,7 @@ LGraphCanvas.prototype.setCanvas = function(canvas) this._mousemove_callback = this.processMouseMove.bind(this); this._mouseup_callback = this.processMouseUp.bind(this); - this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this) ); //down do not need to store the binded + this.canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded this.canvas.addEventListener("mousemove", this._mousemove_callback); this.canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; }); @@ -2083,6 +2113,14 @@ LGraphCanvas.prototype.UIinit = function() } */ +/** +* marks as dirty the canvas, this way it will be rendered again +* +* @class LGraphCanvas +* @method setDirty +* @param {bool} fgcanvas if the foreground canvas is dirty (the one containing the nodes) +* @param {bool} bgcanvas if the background canvas is dirty (the one containing the wires) +*/ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) { if(fgcanvas) @@ -2091,13 +2129,23 @@ LGraphCanvas.prototype.setDirty = function(fgcanvas,bgcanvas) this.dirty_bgcanvas = true; } -//Used to attach the canvas in a popup +/** +* Used to attach the canvas in a popup +* +* @method getCanvasWindow +* @return {window} returns the window where the canvas is attached (the DOM root node) +*/ LGraphCanvas.prototype.getCanvasWindow = function() { var doc = this.canvas.ownerDocument; return doc.defaultView || doc.parentWindow; } +/** +* starts rendering the content of the canvas when needed +* +* @method startRendering +*/ LGraphCanvas.prototype.startRendering = function() { if(this.is_rendering) return; //already rendering @@ -2124,6 +2172,11 @@ LGraphCanvas.prototype.startRendering = function() */ } +/** +* stops rendering the content of the canvas (to save resources) +* +* @method stopRendering +*/ LGraphCanvas.prototype.stopRendering = function() { this.is_rendering = false; @@ -2148,8 +2201,8 @@ LGraphCanvas.prototype.processMouseDown = function(e) var document = ref_window.document; this.canvas.removeEventListener("mousemove", this._mousemove_callback ); - ref_window.document.addEventListener("mousemove", this._mousemove_callback ); //catch for the entire window - ref_window.document.addEventListener("mouseup", this._mouseup_callback ); + ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window + ref_window.document.addEventListener("mouseup", this._mouseup_callback, true ); var n = this.graph.getNodeOnPos(e.canvasX, e.canvasY, this.visible_nodes); var skip_dragging = false; diff --git a/src/nodes/math.js b/src/nodes/math.js index bafc79119..6d45045e9 100644 --- a/src/nodes/math.js +++ b/src/nodes/math.js @@ -146,7 +146,6 @@ function MathOperation() this.addInput("A","number"); this.addInput("B","number"); this.addOutput("A+B","number"); - this.size = [80,20]; this.properties = {A:1.0, B:1.0}; } @@ -252,12 +251,34 @@ MathCompare.prototype.onGetOutputs = function() LiteGraph.registerNodeType("math/compare",MathCompare); +function MathAccumulate() +{ + this.addInput("inc","number"); + this.addOutput("total","number"); + this.properties = { increment: 0, value: 0 }; +} + +MathAccumulate.title = "Accumulate"; +MathAccumulate.desc = "Increments a value every time"; + +MathAccumulate.prototype.onExecute = function() +{ + var inc = this.getInputData(0); + if(inc !== null) + this.properties.value += inc; + else + this.properties.value += this.properties.increment; + this.setOutputData(0, this.properties.value ); +} + +LiteGraph.registerNodeType("math/accumulate", MathAccumulate); + //Math Trigonometry function MathTrigonometry() { this.addInput("v","number"); this.addOutput("sin","number"); - this.properties = {amplitude:1.0}; + this.properties = {amplitude:1.0, offset: 0}; this.bgImageUrl = "nodes/imgs/icon-sin.png"; } @@ -267,7 +288,15 @@ MathTrigonometry.desc = "Sin Cos Tan"; MathTrigonometry.prototype.onExecute = function() { var v = this.getInputData(0); - var amp = this.properties["amplitude"]; + var amplitude = this.properties["amplitude"]; + var slot = this.findInputSlot("amplitude"); + if(slot != -1) + amplitude = this.getInputData(slot); + var offset = this.properties["offset"]; + slot = this.findInputSlot("offset"); + if(slot != -1) + offset = this.getInputData(slot); + for(var i = 0, l = this.outputs.length; i < l; ++i) { var output = this.outputs[i]; @@ -280,10 +309,16 @@ MathTrigonometry.prototype.onExecute = function() case "acos": value = Math.acos(v); break; case "atan": value = Math.atan(v); break; } - this.setOutputData(i, amp * value ); + this.setOutputData(i, amplitude * value + offset); } } +MathTrigonometry.prototype.onGetInputs = function() +{ + return [["v","number"],["amplitude","number"],["offset","number"]]; +} + + MathTrigonometry.prototype.onGetOutputs = function() { return [["sin","number"],["cos","number"],["tan","number"],["asin","number"],["acos","number"],["atan","number"]]; @@ -373,6 +408,7 @@ if(window.glMatrix) { this.addInputs([["x","number"],["y","number"],["z","number"]]); this.addOutput("vec3","vec3"); + this.properties = {x:0, y:0, z:0}; } Math3DXYZToVec3.title = "XYZ->Vec3"; @@ -381,11 +417,11 @@ if(window.glMatrix) Math3DXYZToVec3.prototype.onExecute = function() { var x = this.getInputData(0); - if(x == null) x = 0; + if(x == null) x = this.properties.x; var y = this.getInputData(1); - if(y == null) y = 0; + if(y == null) y = this.properties.y; var z = this.getInputData(2); - if(z == null) z = 0; + if(z == null) z = this.properties.z; this.setOutputData( 0, vec3.fromValues(x,y,z) ); }