diff --git a/build/litegraph.js b/build/litegraph.js
index 883837df2..7d49fd8ab 100644
--- a/build/litegraph.js
+++ b/build/litegraph.js
@@ -746,9 +746,10 @@ LGraph.prototype.findNodesByClass = function(classObject)
LGraph.prototype.findNodesByType = function(type)
{
+ var type = type.toLowerCase();
var r = [];
for(var i in this._nodes)
- if(this._nodes[i].type == type)
+ if(this._nodes[i].type.toLowerCase() == type )
r.push(this._nodes[i]);
return r;
}
@@ -852,7 +853,7 @@ LGraph.prototype.changeGlobalInputType = function(name, type)
if(!this.global_inputs[name])
return false;
- if(this.global_inputs[name].type == type)
+ if(this.global_inputs[name].type.toLowerCase() == type.toLowerCase() )
return;
this.global_inputs[name].type = type;
@@ -933,7 +934,7 @@ LGraph.prototype.changeGlobalOutputType = function(name, type)
if(!this.global_outputs[name])
return false;
- if(this.global_outputs[name].type == type)
+ if(this.global_outputs[name].type.toLowerCase() == type.toLowerCase() )
return;
this.global_outputs[name].type = type;
@@ -1725,7 +1726,7 @@ LGraphNode.prototype.connect = function(slot, node, target_slot)
}
else if( !output.type || //generic output
!node.inputs[target_slot].type || //generic input
- output.type == node.inputs[target_slot].type) //same type
+ output.type.toLowerCase() == node.inputs[target_slot].type.toLowerCase() ) //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 ];
@@ -2045,16 +2046,13 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas)
* @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, skip_render)
+function LGraphCanvas( canvas, graph, skip_render )
{
//if(graph === undefined)
// throw ("No graph assigned");
- if(typeof(canvas) == "string")
- canvas = document.querySelector(canvas);
-
- if(!canvas)
- throw("no canvas found");
+ if(canvas && canvas.constructor === String )
+ canvas = document.querySelector( canvas );
this.max_zoom = 10;
this.min_zoom = 0.1;
@@ -2063,7 +2061,7 @@ function LGraphCanvas(canvas, graph, skip_render)
if(graph)
graph.attachCanvas(this);
- this.setCanvas(canvas);
+ this.setCanvas( canvas );
this.clear();
if(!skip_render)
@@ -2098,9 +2096,7 @@ LGraphCanvas.prototype.clear = function()
this.editor_alpha = 1; //used for transition
this.pause_rendering = false;
this.render_shadows = true;
- this.dirty_canvas = true;
- this.dirty_bgcanvas = true;
- this.dirty_area = null;
+ this.clear_background = true;
this.render_only_selected = true;
this.live_mode = false;
@@ -2108,6 +2104,10 @@ LGraphCanvas.prototype.clear = function()
this.allow_dragcanvas = true;
this.allow_dragnodes = true;
+ this.dirty_canvas = true;
+ this.dirty_bgcanvas = true;
+ this.dirty_area = null;
+
this.node_in_panel = null;
this.last_mouse = [0,0];
@@ -2133,10 +2133,13 @@ LGraphCanvas.prototype.clear = function()
* @method setGraph
* @param {LGraph} graph
*/
-LGraphCanvas.prototype.setGraph = function(graph)
+LGraphCanvas.prototype.setGraph = function( graph, skip_clear )
{
- if(this.graph == graph) return;
- this.clear();
+ if(this.graph == graph)
+ return;
+
+ if(!skip_clear)
+ this.clear();
if(!graph && this.graph)
{
@@ -2203,19 +2206,35 @@ LGraphCanvas.prototype.closeSubgraph = function()
* @method setCanvas
* @param {Canvas} assigns a canvas
*/
-LGraphCanvas.prototype.setCanvas = function(canvas)
+LGraphCanvas.prototype.setCanvas = function( canvas, skip_events )
{
var that = this;
- //Canvas association
- if(typeof(canvas) == "string")
- canvas = document.getElementById(canvas);
+ if(canvas)
+ {
+ if( canvas.constructor === String )
+ {
+ canvas = document.getElementById(canvas);
+ if(!canvas)
+ throw("Error creating LiteGraph canvas: Canvas not found");
+ }
+ }
- if(canvas == null)
- throw("Error creating LiteGraph canvas: Canvas not found");
- if(canvas == this.canvas) return;
+ if(canvas === this.canvas)
+ return;
+
+ if(!canvas && this.canvas)
+ {
+ //maybe detach events from old_canvas
+ if(!skip_events)
+ this.unbindEvents();
+ }
this.canvas = canvas;
+
+ if(!canvas)
+ return;
+
//this.canvas.tabindex = "1000";
canvas.className += " lgraphcanvas";
canvas.data = this;
@@ -2245,72 +2264,85 @@ LGraphCanvas.prototype.setCanvas = function(canvas)
this._mousemove_callback = this.processMouseMove.bind(this);
this._mouseup_callback = this.processMouseUp.bind(this);
- canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded
- canvas.addEventListener("mousemove", this._mousemove_callback);
+ if(!skip_events)
+ this.bindEvents();
+}
- canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; });
-
- canvas.addEventListener("mousewheel", this.processMouseWheel.bind(this), false);
- canvas.addEventListener("DOMMouseScroll", this.processMouseWheel.bind(this), false);
+//used in some events to capture them
+LGraphCanvas.prototype._doNothing = function doNothing() { return false; };
+
+LGraphCanvas.prototype.bindEvents = function()
+{
+ if( this._events_binded )
+ {
+ console.warn("LGraphCanvas: events already binded");
+ return;
+ }
+
+ var canvas = this.canvas;
+
+ this._mousedown_callback = this.processMouseDown.bind(this);
+ this._mousewheel_callback = this.processMouseWheel.bind(this);
+
+ canvas.addEventListener("mousedown", this._mousedown_callback, true ); //down do not need to store the binded
+ canvas.addEventListener("mousemove", this._mousemove_callback );
+ canvas.addEventListener("mousewheel", this._mousewheel_callback, false);
+
+ canvas.addEventListener("contextmenu", this._doNothing );
+ canvas.addEventListener("DOMMouseScroll", this._mousewheel_callback, false);
//touch events
//if( 'touchstart' in document.documentElement )
{
- //alert("doo");
canvas.addEventListener("touchstart", this.touchHandler, true);
canvas.addEventListener("touchmove", this.touchHandler, true);
canvas.addEventListener("touchend", this.touchHandler, true);
canvas.addEventListener("touchcancel", this.touchHandler, true);
}
- //this.canvas.onselectstart = function () { return false; };
- canvas.addEventListener("keydown", function(e) {
- that.processKeyDown(e);
- });
+ //Keyboard ******************
+ this._key_callback = this.processKey.bind(this);
- canvas.addEventListener("keyup", function(e) {
- that.processKeyUp(e);
- });
+ canvas.addEventListener("keydown", this._key_callback );
+ canvas.addEventListener("keyup", this._key_callback );
- //droping files
- canvas.ondragover = function () { console.log('hover'); return false; };
- canvas.ondragend = function () { console.log('out'); return false; };
- canvas.ondrop = function (e) {
- e.preventDefault();
- that.adjustMouseEvent(e);
+ //Droping Stuff over nodes ************************************
+ this._ondrop_callback = this.processDrop.bind(this);
- var pos = [e.canvasX,e.canvasY];
- var node = that.graph.getNodeOnPos(pos[0],pos[1]);
- if(!node)
- return;
+ canvas.addEventListener("dragover", this._doNothing, false );
+ canvas.addEventListener("dragend", this._doNothing, false );
+ canvas.addEventListener("drop", this._ondrop_callback, false );
- if(!node.onDropFile)
- return;
+ this._events_binded = true;
+}
- var file = e.dataTransfer.files[0];
- var filename = file.name;
- var ext = LGraphCanvas.getFileExtension( filename );
- //console.log(file);
+LGraphCanvas.prototype.unbindEvents = function()
+{
+ if( !this._events_binded )
+ {
+ console.warn("LGraphCanvas: no events binded");
+ return;
+ }
- //prepare reader
- var reader = new FileReader();
- reader.onload = function (event) {
- //console.log(event.target);
- var data = event.target.result;
- node.onDropFile( data, filename, file );
- };
+ this.canvas.removeEventListener( "mousedown", this._mousedown_callback );
+ this.canvas.removeEventListener( "mousewheel", this._mousewheel_callback );
+ this.canvas.removeEventListener( "DOMMouseScroll", this._mousewheel_callback );
+ this.canvas.removeEventListener( "keydown", this._key_callback );
+ this.canvas.removeEventListener( "keyup", this._key_callback );
+ this.canvas.removeEventListener( "contextmenu", this._doNothing );
+ this.canvas.removeEventListener( "drop", this._ondrop_callback );
- //read data
- var type = file.type.split("/")[0];
- if(type == "text" || type == "")
- reader.readAsText(file);
- else if (type == "image")
- reader.readAsDataURL(file);
- else
- reader.readAsArrayBuffer(file);
+ this.canvas.removeEventListener("touchstart", this.touchHandler );
+ this.canvas.removeEventListener("touchmove", this.touchHandler );
+ this.canvas.removeEventListener("touchend", this.touchHandler );
+ this.canvas.removeEventListener("touchcancel", this.touchHandler );
- return false;
- };
+ this._mousedown_callback = null;
+ this._mousewheel_callback = null;
+ this._key_callback = null;
+ this._ondrop_callback = null;
+
+ this._events_binded = false;
}
LGraphCanvas.getFileExtension = function (url)
@@ -2467,13 +2499,15 @@ LGraphCanvas.prototype.stopRendering = function()
LGraphCanvas.prototype.processMouseDown = function(e)
{
- if(!this.graph) return;
+ if(!this.graph)
+ return;
this.adjustMouseEvent(e);
var ref_window = this.getCanvasWindow();
var document = ref_window.document;
+ //move mouse move event to the window in case it drags outside of the canvas
this.canvas.removeEventListener("mousemove", this._mousemove_callback );
ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
@@ -2699,7 +2733,7 @@ LGraphCanvas.prototype.processMouseMove = function(e)
if(slot != -1 && n.inputs[slot])
{
var slot_type = n.inputs[slot].type;
- if(slot_type == this.connecting_output.type || !slot_type || !this.connecting_output.type )
+ if( !this.connecting_output.type || !slot_type || slot_type.toLowerCase() == this.connecting_output.type.toLowerCase() )
this._highlight_input = pos;
}
else
@@ -2774,11 +2808,13 @@ LGraphCanvas.prototype.processMouseMove = function(e)
LGraphCanvas.prototype.processMouseUp = function(e)
{
- if(!this.graph) return;
+ if(!this.graph)
+ return;
var window = this.getCanvasWindow();
var document = window.document;
+ //restore the mousemove event back to the canvas
document.removeEventListener("mousemove", this._mousemove_callback, true );
this.canvas.addEventListener("mousemove", this._mousemove_callback, true);
document.removeEventListener("mouseup", this._mouseup_callback, true );
@@ -2815,7 +2851,7 @@ LGraphCanvas.prototype.processMouseUp = function(e)
{ //not on top of an input
var input = node.getInputInfo(0);
//simple connect
- if(input && !input.link && input.type == this.connecting_output.type)
+ if(input && !input.link && input.type == this.connecting_output.type) //toLowerCase missing
this.connecting_node.connect(this.connecting_slot, node, 0);
}
}
@@ -2879,75 +2915,11 @@ LGraphCanvas.prototype.processMouseUp = function(e)
return false;
}
-LGraphCanvas.prototype.isOverNodeInput = function(node, canvasx, canvasy, slot_pos)
-{
- if(node.inputs)
- for(var i = 0, l = node.inputs.length; i < l; ++i)
- {
- var input = node.inputs[i];
- var link_pos = node.getConnectionPos(true,i);
- if( isInsideRectangle(canvasx, canvasy, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
- {
- if(slot_pos) { slot_pos[0] = link_pos[0]; slot_pos[1] = link_pos[1] };
- return i;
- }
- }
- return -1;
-}
-
-LGraphCanvas.prototype.processKeyDown = function(e)
-{
- if(!this.graph) return;
- var block_default = false;
-
- //select all Control A
- if(e.keyCode == 65 && e.ctrlKey)
- {
- this.selectAllNodes();
- block_default = true;
- }
-
- //delete or backspace
- if(e.keyCode == 46 || e.keyCode == 8)
- {
- this.deleteSelectedNodes();
- block_default = true;
- }
-
- //collapse
- //...
-
- //TODO
- if(this.selected_nodes)
- for (var i in this.selected_nodes)
- if(this.selected_nodes[i].onKeyDown)
- this.selected_nodes[i].onKeyDown(e);
-
- this.graph.change();
-
- if(block_default)
- {
- e.preventDefault();
- return false;
- }
-}
-
-LGraphCanvas.prototype.processKeyUp = function(e)
-{
- if(!this.graph) return;
- //TODO
- if(this.selected_nodes)
- for (var i in this.selected_nodes)
- if(this.selected_nodes[i].onKeyUp)
- this.selected_nodes[i].onKeyUp(e);
-
- this.graph.change();
-}
LGraphCanvas.prototype.processMouseWheel = function(e)
{
- if(!this.graph) return;
- if(!this.allow_dragcanvas) return;
+ if(!this.graph || !this.allow_dragcanvas)
+ return;
var delta = (e.wheelDeltaY != null ? e.wheelDeltaY : e.detail * -60);
@@ -2973,6 +2945,109 @@ LGraphCanvas.prototype.processMouseWheel = function(e)
return false; // prevent default
}
+LGraphCanvas.prototype.isOverNodeInput = function(node, canvasx, canvasy, slot_pos)
+{
+ if(node.inputs)
+ for(var i = 0, l = node.inputs.length; i < l; ++i)
+ {
+ var input = node.inputs[i];
+ var link_pos = node.getConnectionPos(true,i);
+ if( isInsideRectangle(canvasx, canvasy, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
+ {
+ if(slot_pos) { slot_pos[0] = link_pos[0]; slot_pos[1] = link_pos[1] };
+ return i;
+ }
+ }
+ return -1;
+}
+
+LGraphCanvas.prototype.processKey = function(e)
+{
+ if(!this.graph)
+ return;
+
+ var block_default = false;
+
+ if(e.type == "keydown")
+ {
+ //select all Control A
+ if(e.keyCode == 65 && e.ctrlKey)
+ {
+ this.selectAllNodes();
+ block_default = true;
+ }
+
+ //delete or backspace
+ if(e.keyCode == 46 || e.keyCode == 8)
+ {
+ this.deleteSelectedNodes();
+ block_default = true;
+ }
+
+ //collapse
+ //...
+
+ //TODO
+ if(this.selected_nodes)
+ for (var i in this.selected_nodes)
+ if(this.selected_nodes[i].onKeyDown)
+ this.selected_nodes[i].onKeyDown(e);
+ }
+ else if( e.type == "keyup" )
+ {
+ if(this.selected_nodes)
+ for (var i in this.selected_nodes)
+ if(this.selected_nodes[i].onKeyUp)
+ this.selected_nodes[i].onKeyUp(e);
+ }
+
+ this.graph.change();
+
+ if(block_default)
+ {
+ e.preventDefault();
+ return false;
+ }
+}
+
+LGraphCanvas.prototype.processDrop = function(e)
+{
+ e.preventDefault();
+ this.adjustMouseEvent(e);
+
+ var pos = [e.canvasX,e.canvasY];
+ var node = this.graph.getNodeOnPos(pos[0],pos[1]);
+ if(!node)
+ return;
+
+ if(!node.onDropFile)
+ return;
+
+ var file = e.dataTransfer.files[0];
+ var filename = file.name;
+ var ext = LGraphCanvas.getFileExtension( filename );
+ //console.log(file);
+
+ //prepare reader
+ var reader = new FileReader();
+ reader.onload = function (event) {
+ //console.log(event.target);
+ var data = event.target.result;
+ node.onDropFile( data, filename, file );
+ };
+
+ //read data
+ var type = file.type.split("/")[0];
+ if(type == "text" || type == "")
+ reader.readAsText(file);
+ else if (type == "image")
+ reader.readAsDataURL(file);
+ else
+ reader.readAsArrayBuffer(file);
+
+ return false;
+}
+
LGraphCanvas.prototype.processNodeSelected = function(n,e)
{
n.selected = true;
@@ -3228,7 +3303,8 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
//clear
//canvas.width = canvas.width;
- ctx.clearRect(0,0,canvas.width, canvas.height);
+ if(this.clear_background)
+ ctx.clearRect(0,0,canvas.width, canvas.height);
//draw bg canvas
if(this.bgcanvas == this.canvas)
@@ -3242,19 +3318,7 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
//info widget
if(this.show_info)
- {
- ctx.font = "10px Arial";
- ctx.fillStyle = "#888";
- if(this.graph)
- {
- ctx.fillText( "T: " + this.graph.globaltime.toFixed(2)+"s",5,13*1 );
- ctx.fillText( "I: " + this.graph.iteration,5,13*2 );
- ctx.fillText( "F: " + this.frame,5,13*3 );
- ctx.fillText( "FPS:" + this.fps.toFixed(2),5,13*4 );
- }
- else
- ctx.fillText( "No graph selected",5,13*1 );
- }
+ this.renderInfo(ctx);
if(this.graph)
{
@@ -3329,6 +3393,28 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
this.dirty_canvas = false;
}
+LGraphCanvas.prototype.renderInfo = function( ctx, x, y )
+{
+ x = x || 0;
+ y = y || 0;
+
+ ctx.save();
+ ctx.translate( x, y );
+
+ ctx.font = "10px Arial";
+ ctx.fillStyle = "#888";
+ if(this.graph)
+ {
+ ctx.fillText( "T: " + this.graph.globaltime.toFixed(2)+"s",5,13*1 );
+ ctx.fillText( "I: " + this.graph.iteration,5,13*2 );
+ ctx.fillText( "F: " + this.frame,5,13*3 );
+ ctx.fillText( "FPS:" + this.fps.toFixed(2),5,13*4 );
+ }
+ else
+ ctx.fillText( "No graph selected",5,13*1 );
+ ctx.restore();
+}
+
LGraphCanvas.prototype.drawBackCanvas = function()
{
var canvas = this.bgcanvas;
@@ -3339,7 +3425,8 @@ LGraphCanvas.prototype.drawBackCanvas = function()
ctx.start();
//clear
- ctx.clearRect(0,0,canvas.width, canvas.height);
+ if(this.clear_background)
+ ctx.clearRect(0,0,canvas.width, canvas.height);
//reset in case of error
ctx.restore();
@@ -3540,7 +3627,7 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var slot = node.inputs[i];
ctx.globalAlpha = editor_alpha;
- if (this.connecting_node != null && this.connecting_output.type != 0 && node.inputs[i].type != 0 && this.connecting_output.type != node.inputs[i].type)
+ if (this.connecting_node != null && this.connecting_output.type && node.inputs[i].type && this.connecting_output.type.toLowerCase() != node.inputs[i].type.toLowerCase() )
ctx.globalAlpha = 0.4 * editor_alpha;
ctx.fillStyle = slot.link != null ? "#7F7" : "#AAA";
@@ -4788,7 +4875,7 @@ Subgraph.prototype.clone = function()
}
-LiteGraph.registerNodeType("graph/subgraph", Subgraph);
+LiteGraph.registerNodeType("graph/subgraph", Subgraph );
//Input for a subgraph
@@ -5738,6 +5825,138 @@ LiteGraph.registerNodeType("basic/console", Console );
})();
(function(){
+function GamepadInput()
+{
+ this.addOutput("left_x_axis","number");
+ this.addOutput("left_y_axis","number");
+ this.properties = {};
+}
+
+GamepadInput.title = "Gamepad";
+GamepadInput.desc = "gets the input of the gamepad";
+
+GamepadInput.prototype.onExecute = function()
+{
+ //get gamepad
+ var gamepad = this.getGamepad();
+ if(!gamepad)
+ return;
+
+ if(this.outputs)
+ {
+ for(var i = 0; i < this.outputs.length; i++)
+ {
+ var output = this.outputs[i];
+ var v = null;
+ switch( output.name )
+ {
+ case "left_x_axis": v = gamepad.xbox.axes["lx"]; break;
+ case "left_y_axis": v = gamepad.xbox.axes["ly"]; break;
+ case "right_x_axis": v = gamepad.xbox.axes["rx"]; break;
+ case "right_y_axis": v = gamepad.xbox.axes["ry"]; break;
+ case "a_button": v = gamepad.xbox.buttons["a"] ? 1 : 0; break;
+ case "b_button": v = gamepad.xbox.buttons["b"] ? 1 : 0; break;
+ case "x_button": v = gamepad.xbox.buttons["x"] ? 1 : 0; break;
+ case "y_button": v = gamepad.xbox.buttons["y"] ? 1 : 0; break;
+ case "lb_button": v = gamepad.xbox.buttons["lb"] ? 1 : 0; break;
+ case "rb_button": v = gamepad.xbox.buttons["rb"] ? 1 : 0; break;
+ case "ls_button": v = gamepad.xbox.buttons["ls"] ? 1 : 0; break;
+ case "rs_button": v = gamepad.xbox.buttons["rs"] ? 1 : 0; break;
+ case "start_button": v = gamepad.xbox.buttons["start"] ? 1 : 0; break;
+ case "back_button": v = gamepad.xbox.buttons["back"] ? 1 : 0; break;
+ default: break;
+ }
+ this.setOutputData(i,v);
+ }
+ }
+}
+
+GamepadInput.prototype.getGamepad = function()
+{
+ var getGamepads = navigator.getGamepads || navigator.webkitGetGamepads || navigator.mozGetGamepads;
+ if(!getGamepads)
+ return null;
+ var gamepads = getGamepads.call(navigator);
+ var gamepad = null;
+
+ for(var i = 0; i < 4; i++)
+ {
+ if (gamepads[i])
+ {
+ gamepad = gamepads[i];
+
+ //xbox controller mapping
+ var xbox = this.xbox_mapping;
+ if(!xbox)
+ xbox = this.xbox_mapping = { axes:[], buttons:{}, hat: ""};
+
+ xbox.axes["lx"] = gamepad.axes[0];
+ xbox.axes["ly"] = gamepad.axes[1];
+ xbox.axes["rx"] = gamepad.axes[2];
+ xbox.axes["ry"] = gamepad.axes[3];
+ xbox.axes["triggers"] = gamepad.axes[4];
+
+ for(var i = 0; i < gamepad.buttons.length; i++)
+ {
+ //mapping of XBOX
+ switch(i) //I use a switch to ensure that a player with another gamepad could play
+ {
+ case 0: xbox.buttons["a"] = gamepad.buttons[i].pressed; break;
+ case 1: xbox.buttons["b"] = gamepad.buttons[i].pressed; break;
+ case 2: xbox.buttons["x"] = gamepad.buttons[i].pressed; break;
+ case 3: xbox.buttons["y"] = gamepad.buttons[i].pressed; break;
+ case 4: xbox.buttons["lb"] = gamepad.buttons[i].pressed; break;
+ case 5: xbox.buttons["rb"] = gamepad.buttons[i].pressed; break;
+ case 6: xbox.buttons["lt"] = gamepad.buttons[i].pressed; break;
+ case 7: xbox.buttons["rt"] = gamepad.buttons[i].pressed; break;
+ case 8: xbox.buttons["back"] = gamepad.buttons[i].pressed; break;
+ case 9: xbox.buttons["start"] = gamepad.buttons[i].pressed; break;
+ case 10: xbox.buttons["ls"] = gamepad.buttons[i].pressed; break;
+ case 11: xbox.buttons["rs"] = gamepad.buttons[i].pressed; break;
+ case 12: if( gamepad.buttons[i].pressed) xbox.hat += "up"; break;
+ case 13: if( gamepad.buttons[i].pressed) xbox.hat += "down"; break;
+ case 14: if( gamepad.buttons[i].pressed) xbox.hat += "left"; break;
+ case 15: if( gamepad.buttons[i].pressed) xbox.hat += "right"; break;
+ case 16: xbox.buttons["home"] = gamepad.buttons[i].pressed; break;
+ default:
+ }
+ }
+ gamepad.xbox = xbox;
+ return gamepad;
+ }
+ }
+}
+
+GamepadInput.prototype.onDrawBackground = function(ctx)
+{
+ //render
+}
+
+GamepadInput.prototype.onGetOutputs = function() {
+ return [
+ ["left_x_axis","number"],
+ ["left_y_axis","number"],
+ ["right_x_axis","number"],
+ ["right_y_axis","number"],
+ ["trigger","number"],
+ ["a_button","number"],
+ ["b_button","number"],
+ ["x_button","number"],
+ ["y_button","number"],
+ ["lb_button","number"],
+ ["rb_button","number"],
+ ["ls_button","number"],
+ ["rs_button","number"],
+ ["start","number"],
+ ["back","number"]
+ ];
+}
+
+LiteGraph.registerNodeType("input/gamepad", GamepadInput );
+
+})();
+(function(){
+
function MathRand()
{
diff --git a/build/litegraph.min.js b/build/litegraph.min.js
index 7c5949528..890311d83 100644
--- a/build/litegraph.min.js
+++ b/build/litegraph.min.js
@@ -16,13 +16,13 @@ LGraph.prototype.sendEventToAllNodes=function(a,b){var c=this._nodes_in_order?th
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;b../src/litegraph.js:1076
+ ../src/litegraph.js:1077
../src/litegraph.js:755
+ ../src/litegraph.js:756
@@ -1393,7 +1393,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:771
+ ../src/litegraph.js:772
@@ -1591,7 +1591,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:1010
+ ../src/litegraph.js:1011
@@ -1939,7 +1939,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:1043
+ ../src/litegraph.js:1044
@@ -2024,7 +2024,7 @@ if the nodes are using graphical actions
- ../src/litegraph.js:958
+ ../src/litegraph.js:959
@@ -2134,7 +2134,7 @@ can be easily accesed from the outside of the graph
- ../src/litegraph.js:973
+ ../src/litegraph.js:974
diff --git a/doc/classes/LGraphCanvas.html b/doc/classes/LGraphCanvas.html
index 5cfdb1acf..1beee8603 100644
--- a/doc/classes/LGraphCanvas.html
+++ b/doc/classes/LGraphCanvas.html
@@ -96,7 +96,7 @@
../src/litegraph.js:2397
+ Defined in: ../src/litegraph.js:2429
../src/litegraph.js:2397
+ ../src/litegraph.js:2429
@@ -353,7 +353,7 @@
- ../src/litegraph.js:2075
+ ../src/litegraph.js:2073
@@ -418,7 +418,7 @@
- ../src/litegraph.js:2184
+ ../src/litegraph.js:2187
@@ -501,7 +501,7 @@
- ../src/litegraph.js:2413
+ ../src/litegraph.js:2445
@@ -580,7 +580,7 @@
- ../src/litegraph.js:2157
+ ../src/litegraph.js:2160
@@ -668,7 +668,7 @@
- ../src/litegraph.js:2199
+ ../src/litegraph.js:2202
@@ -835,7 +835,7 @@
- ../src/litegraph.js:2425
+ ../src/litegraph.js:2457
@@ -890,7 +890,7 @@
- ../src/litegraph.js:2448
+ ../src/litegraph.js:2480
diff --git a/doc/classes/LGraphNode.html b/doc/classes/LGraphNode.html
index 03e383242..340df53ec 100644
--- a/doc/classes/LGraphNode.html
+++ b/doc/classes/LGraphNode.html
@@ -96,7 +96,7 @@
../src/litegraph.js:1155
+ Defined in: ../src/litegraph.js:1156
../src/litegraph.js:1569
+ ../src/litegraph.js:1570
@@ -563,7 +563,7 @@
- ../src/litegraph.js:1508
+ ../src/litegraph.js:1509
@@ -683,7 +683,7 @@
- ../src/litegraph.js:1530
+ ../src/litegraph.js:1531
@@ -784,7 +784,7 @@
- ../src/litegraph.js:1448
+ ../src/litegraph.js:1449
@@ -904,7 +904,7 @@
- ../src/litegraph.js:1469
+ ../src/litegraph.js:1470
@@ -983,7 +983,7 @@
- ../src/litegraph.js:2001
+ ../src/litegraph.js:2002
@@ -1052,7 +1052,7 @@
- ../src/litegraph.js:1582
+ ../src/litegraph.js:1583
@@ -1144,7 +1144,7 @@
- ../src/litegraph.js:1190
+ ../src/litegraph.js:1191
@@ -1225,7 +1225,7 @@
- ../src/litegraph.js:1662
+ ../src/litegraph.js:1663
@@ -1364,7 +1364,7 @@
- ../src/litegraph.js:1812
+ ../src/litegraph.js:1813
@@ -1477,7 +1477,7 @@
- ../src/litegraph.js:1745
+ ../src/litegraph.js:1746
@@ -1600,7 +1600,7 @@
- ../src/litegraph.js:1632
+ ../src/litegraph.js:1633
@@ -1707,7 +1707,7 @@
- ../src/litegraph.js:1647
+ ../src/litegraph.js:1648
@@ -1804,7 +1804,7 @@
- ../src/litegraph.js:1600
+ ../src/litegraph.js:1601
@@ -1893,7 +1893,7 @@
- ../src/litegraph.js:1869
+ ../src/litegraph.js:1870
@@ -2016,7 +2016,7 @@
- ../src/litegraph.js:1349
+ ../src/litegraph.js:1350
@@ -2122,7 +2122,7 @@
- ../src/litegraph.js:1377
+ ../src/litegraph.js:1378
@@ -2226,7 +2226,7 @@
- ../src/litegraph.js:1392
+ ../src/litegraph.js:1393
@@ -2330,7 +2330,7 @@
- ../src/litegraph.js:1419
+ ../src/litegraph.js:1420
@@ -2420,7 +2420,7 @@
- ../src/litegraph.js:1315
+ ../src/litegraph.js:1316
@@ -2489,7 +2489,7 @@
- ../src/litegraph.js:1364
+ ../src/litegraph.js:1365
@@ -2593,7 +2593,7 @@
- ../src/litegraph.js:1407
+ ../src/litegraph.js:1408
@@ -2703,7 +2703,7 @@
- ../src/litegraph.js:1610
+ ../src/litegraph.js:1611
@@ -2808,7 +2808,7 @@
- ../src/litegraph.js:2014
+ ../src/litegraph.js:2015
@@ -2873,7 +2873,7 @@
- ../src/litegraph.js:1555
+ ../src/litegraph.js:1556
@@ -2961,7 +2961,7 @@
- ../src/litegraph.js:1494
+ ../src/litegraph.js:1495
@@ -3039,7 +3039,7 @@
- ../src/litegraph.js:1249
+ ../src/litegraph.js:1250
@@ -3110,7 +3110,7 @@
- ../src/litegraph.js:1328
+ ../src/litegraph.js:1329
@@ -3203,7 +3203,7 @@
- ../src/litegraph.js:1303
+ ../src/litegraph.js:1304
diff --git a/doc/data.json b/doc/data.json
index ff262682c..3affa1f0c 100644
--- a/doc/data.json
+++ b/doc/data.json
@@ -51,7 +51,7 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
- "line": 1155,
+ "line": 1156,
"description": "Base Class for all the node type classes",
"params": [
{
@@ -70,7 +70,7 @@
"plugin_for": [],
"extension_for": [],
"file": "../src/litegraph.js",
- "line": 2397,
+ "line": 2429,
"description": "marks as dirty the canvas, this way it will be rendered again",
"is_constructor": 1,
"params": [
@@ -409,7 +409,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 755,
+ "line": 756,
"description": "Returns a list of nodes that matches a name",
"itemtype": "method",
"name": "findNodesByName",
@@ -428,7 +428,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 771,
+ "line": 772,
"description": "Returns the top-most node in this position of the canvas",
"itemtype": "method",
"name": "getNodeOnPos",
@@ -457,7 +457,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 958,
+ "line": 959,
"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",
@@ -477,7 +477,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 973,
+ "line": 974,
"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",
@@ -496,7 +496,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1010,
+ "line": 1011,
"description": "returns if the graph is in live mode",
"itemtype": "method",
"name": "isLive",
@@ -504,7 +504,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1043,
+ "line": 1044,
"description": "Creates a Object containing all the info about this graph, it can be serialized",
"itemtype": "method",
"name": "serialize",
@@ -516,7 +516,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1076,
+ "line": 1077,
"description": "Configure a graph from a JSON string",
"itemtype": "method",
"name": "configure",
@@ -531,7 +531,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1190,
+ "line": 1191,
"description": "configure a node from an object containing the serialized info",
"itemtype": "method",
"name": "configure",
@@ -539,7 +539,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1249,
+ "line": 1250,
"description": "serialize the content",
"itemtype": "method",
"name": "serialize",
@@ -547,7 +547,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1303,
+ "line": 1304,
"description": "serialize and stringify",
"itemtype": "method",
"name": "toString",
@@ -555,7 +555,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1315,
+ "line": 1316,
"description": "get the title string",
"itemtype": "method",
"name": "getTitle",
@@ -563,7 +563,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1328,
+ "line": 1329,
"description": "sets the output data",
"itemtype": "method",
"name": "setOutputData",
@@ -583,7 +583,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1349,
+ "line": 1350,
"description": "retrieves the input data (data traveling through the connection) from one slot",
"itemtype": "method",
"name": "getInputData",
@@ -602,7 +602,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1364,
+ "line": 1365,
"description": "tells you if there is a connection in one input slot",
"itemtype": "method",
"name": "isInputConnected",
@@ -621,7 +621,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1377,
+ "line": 1378,
"description": "tells you info about an input connection (which node, type, etc)",
"itemtype": "method",
"name": "getInputInfo",
@@ -640,7 +640,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1392,
+ "line": 1393,
"description": "tells you info about an output connection (which node, type, etc)",
"itemtype": "method",
"name": "getOutputInfo",
@@ -659,7 +659,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1407,
+ "line": 1408,
"description": "tells you if there is a connection in one output slot",
"itemtype": "method",
"name": "isOutputConnected",
@@ -678,7 +678,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1419,
+ "line": 1420,
"description": "retrieves all the nodes connected to this output slot",
"itemtype": "method",
"name": "getOutputNodes",
@@ -697,7 +697,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1448,
+ "line": 1449,
"description": "add a new output slot to use in this node",
"itemtype": "method",
"name": "addOutput",
@@ -722,7 +722,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1469,
+ "line": 1470,
"description": "add a new output slot to use in this node",
"itemtype": "method",
"name": "addOutputs",
@@ -737,7 +737,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1494,
+ "line": 1495,
"description": "remove an existing output slot",
"itemtype": "method",
"name": "removeOutput",
@@ -752,7 +752,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1508,
+ "line": 1509,
"description": "add a new input slot to use in this node",
"itemtype": "method",
"name": "addInput",
@@ -777,7 +777,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1530,
+ "line": 1531,
"description": "add several new input slots in this node",
"itemtype": "method",
"name": "addInputs",
@@ -792,7 +792,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1555,
+ "line": 1556,
"description": "remove an existing input slot",
"itemtype": "method",
"name": "removeInput",
@@ -807,7 +807,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1569,
+ "line": 1570,
"description": "add an special connection to this node (used for special kinds of graphs)",
"itemtype": "method",
"name": "addConnection",
@@ -837,7 +837,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1582,
+ "line": 1583,
"description": "computes the size of a node according to its inputs and output slots",
"itemtype": "method",
"name": "computeSize",
@@ -856,7 +856,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1600,
+ "line": 1601,
"description": "returns the bounding of the object, used for rendering purposes",
"itemtype": "method",
"name": "getBounding",
@@ -868,7 +868,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1610,
+ "line": 1611,
"description": "checks if a point is inside the shape of a node",
"itemtype": "method",
"name": "isPointInsideNode",
@@ -892,7 +892,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1632,
+ "line": 1633,
"description": "returns the input slot with a given name (used for dynamic slots), -1 if not found",
"itemtype": "method",
"name": "findInputSlot",
@@ -911,7 +911,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1647,
+ "line": 1648,
"description": "returns the output slot with a given name (used for dynamic slots), -1 if not found",
"itemtype": "method",
"name": "findOutputSlot",
@@ -930,7 +930,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1662,
+ "line": 1663,
"description": "connect this node output to the input of another node",
"itemtype": "method",
"name": "connect",
@@ -959,7 +959,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1745,
+ "line": 1746,
"description": "disconnect one output to an specific node",
"itemtype": "method",
"name": "disconnectOutput",
@@ -983,7 +983,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1812,
+ "line": 1813,
"description": "disconnect one input",
"itemtype": "method",
"name": "disconnectInput",
@@ -1002,7 +1002,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 1869,
+ "line": 1870,
"description": "returns the center of a connection point in canvas coords",
"itemtype": "method",
"name": "getConnectionPos",
@@ -1026,7 +1026,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2001,
+ "line": 2002,
"description": "Collapse the node to make it smaller on the canvas",
"itemtype": "method",
"name": "collapse",
@@ -1034,7 +1034,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2014,
+ "line": 2015,
"description": "Forces the node to do not move or realign on Z",
"itemtype": "method",
"name": "pin",
@@ -1042,7 +1042,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2075,
+ "line": 2073,
"description": "clears all the data inside",
"itemtype": "method",
"name": "clear",
@@ -1065,7 +1065,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2157,
+ "line": 2160,
"description": "opens a graph contained inside a node in the current graph",
"itemtype": "method",
"name": "openSubgraph",
@@ -1080,7 +1080,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2184,
+ "line": 2187,
"description": "closes a subgraph contained inside a node",
"itemtype": "method",
"name": "closeSubgraph",
@@ -1095,7 +1095,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2199,
+ "line": 2202,
"description": "assigns a canvas",
"itemtype": "method",
"name": "setCanvas",
@@ -1110,7 +1110,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2413,
+ "line": 2445,
"description": "Used to attach the canvas in a popup",
"itemtype": "method",
"name": "getCanvasWindow",
@@ -1122,7 +1122,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2425,
+ "line": 2457,
"description": "starts rendering the content of the canvas when needed",
"itemtype": "method",
"name": "startRendering",
@@ -1130,7 +1130,7 @@
},
{
"file": "../src/litegraph.js",
- "line": 2448,
+ "line": 2480,
"description": "stops rendering the content of the canvas (to save resources)",
"itemtype": "method",
"name": "stopRendering",
diff --git a/doc/files/.._src_litegraph.js.html b/doc/files/.._src_litegraph.js.html
index 8e88f542b..246040aa1 100644
--- a/doc/files/.._src_litegraph.js.html
+++ b/doc/files/.._src_litegraph.js.html
@@ -839,9 +839,10 @@ LGraph.prototype.findNodesByClass = function(classObject)
LGraph.prototype.findNodesByType = function(type)
{
+ var type = type.toLowerCase();
var r = [];
for(var i in this._nodes)
- if(this._nodes[i].type == type)
+ if(this._nodes[i].type.toLowerCase() == type )
r.push(this._nodes[i]);
return r;
}
@@ -945,7 +946,7 @@ LGraph.prototype.changeGlobalInputType = function(name, type)
if(!this.global_inputs[name])
return false;
- if(this.global_inputs[name].type == type)
+ if(this.global_inputs[name].type.toLowerCase() == type.toLowerCase() )
return;
this.global_inputs[name].type = type;
@@ -1026,7 +1027,7 @@ LGraph.prototype.changeGlobalOutputType = function(name, type)
if(!this.global_outputs[name])
return false;
- if(this.global_outputs[name].type == type)
+ if(this.global_outputs[name].type.toLowerCase() == type.toLowerCase() )
return;
this.global_outputs[name].type = type;
@@ -1818,7 +1819,7 @@ LGraphNode.prototype.connect = function(slot, node, target_slot)
}
else if( !output.type || //generic output
!node.inputs[target_slot].type || //generic input
- output.type == node.inputs[target_slot].type) //same type
+ output.type.toLowerCase() == node.inputs[target_slot].type.toLowerCase() ) //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 ];
@@ -2138,16 +2139,13 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas)
* @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, skip_render)
+function LGraphCanvas( canvas, graph, skip_render )
{
//if(graph === undefined)
// throw ("No graph assigned");
- if(typeof(canvas) == "string")
- canvas = document.querySelector(canvas);
-
- if(!canvas)
- throw("no canvas found");
+ if(canvas && canvas.constructor === String )
+ canvas = document.querySelector( canvas );
this.max_zoom = 10;
this.min_zoom = 0.1;
@@ -2156,7 +2154,7 @@ function LGraphCanvas(canvas, graph, skip_render)
if(graph)
graph.attachCanvas(this);
- this.setCanvas(canvas);
+ this.setCanvas( canvas );
this.clear();
if(!skip_render)
@@ -2191,9 +2189,7 @@ LGraphCanvas.prototype.clear = function()
this.editor_alpha = 1; //used for transition
this.pause_rendering = false;
this.render_shadows = true;
- this.dirty_canvas = true;
- this.dirty_bgcanvas = true;
- this.dirty_area = null;
+ this.clear_background = true;
this.render_only_selected = true;
this.live_mode = false;
@@ -2201,6 +2197,10 @@ LGraphCanvas.prototype.clear = function()
this.allow_dragcanvas = true;
this.allow_dragnodes = true;
+ this.dirty_canvas = true;
+ this.dirty_bgcanvas = true;
+ this.dirty_area = null;
+
this.node_in_panel = null;
this.last_mouse = [0,0];
@@ -2226,10 +2226,13 @@ LGraphCanvas.prototype.clear = function()
* @method setGraph
* @param {LGraph} graph
*/
-LGraphCanvas.prototype.setGraph = function(graph)
+LGraphCanvas.prototype.setGraph = function( graph, skip_clear )
{
- if(this.graph == graph) return;
- this.clear();
+ if(this.graph == graph)
+ return;
+
+ if(!skip_clear)
+ this.clear();
if(!graph && this.graph)
{
@@ -2296,19 +2299,35 @@ LGraphCanvas.prototype.closeSubgraph = function()
* @method setCanvas
* @param {Canvas} assigns a canvas
*/
-LGraphCanvas.prototype.setCanvas = function(canvas)
+LGraphCanvas.prototype.setCanvas = function( canvas, skip_events )
{
var that = this;
- //Canvas association
- if(typeof(canvas) == "string")
- canvas = document.getElementById(canvas);
+ if(canvas)
+ {
+ if( canvas.constructor === String )
+ {
+ canvas = document.getElementById(canvas);
+ if(!canvas)
+ throw("Error creating LiteGraph canvas: Canvas not found");
+ }
+ }
- if(canvas == null)
- throw("Error creating LiteGraph canvas: Canvas not found");
- if(canvas == this.canvas) return;
+ if(canvas === this.canvas)
+ return;
+
+ if(!canvas && this.canvas)
+ {
+ //maybe detach events from old_canvas
+ if(!skip_events)
+ this.unbindEvents();
+ }
this.canvas = canvas;
+
+ if(!canvas)
+ return;
+
//this.canvas.tabindex = "1000";
canvas.className += " lgraphcanvas";
canvas.data = this;
@@ -2338,72 +2357,85 @@ LGraphCanvas.prototype.setCanvas = function(canvas)
this._mousemove_callback = this.processMouseMove.bind(this);
this._mouseup_callback = this.processMouseUp.bind(this);
- canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded
- canvas.addEventListener("mousemove", this._mousemove_callback);
+ if(!skip_events)
+ this.bindEvents();
+}
- canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; });
-
- canvas.addEventListener("mousewheel", this.processMouseWheel.bind(this), false);
- canvas.addEventListener("DOMMouseScroll", this.processMouseWheel.bind(this), false);
+//used in some events to capture them
+LGraphCanvas.prototype._doNothing = function doNothing() { return false; };
+
+LGraphCanvas.prototype.bindEvents = function()
+{
+ if( this._events_binded )
+ {
+ console.warn("LGraphCanvas: events already binded");
+ return;
+ }
+
+ var canvas = this.canvas;
+
+ this._mousedown_callback = this.processMouseDown.bind(this);
+ this._mousewheel_callback = this.processMouseWheel.bind(this);
+
+ canvas.addEventListener("mousedown", this._mousedown_callback, true ); //down do not need to store the binded
+ canvas.addEventListener("mousemove", this._mousemove_callback );
+ canvas.addEventListener("mousewheel", this._mousewheel_callback, false);
+
+ canvas.addEventListener("contextmenu", this._doNothing );
+ canvas.addEventListener("DOMMouseScroll", this._mousewheel_callback, false);
//touch events
//if( 'touchstart' in document.documentElement )
{
- //alert("doo");
canvas.addEventListener("touchstart", this.touchHandler, true);
canvas.addEventListener("touchmove", this.touchHandler, true);
canvas.addEventListener("touchend", this.touchHandler, true);
canvas.addEventListener("touchcancel", this.touchHandler, true);
}
- //this.canvas.onselectstart = function () { return false; };
- canvas.addEventListener("keydown", function(e) {
- that.processKeyDown(e);
- });
+ //Keyboard ******************
+ this._key_callback = this.processKey.bind(this);
- canvas.addEventListener("keyup", function(e) {
- that.processKeyUp(e);
- });
+ canvas.addEventListener("keydown", this._key_callback );
+ canvas.addEventListener("keyup", this._key_callback );
- //droping files
- canvas.ondragover = function () { console.log('hover'); return false; };
- canvas.ondragend = function () { console.log('out'); return false; };
- canvas.ondrop = function (e) {
- e.preventDefault();
- that.adjustMouseEvent(e);
+ //Droping Stuff over nodes ************************************
+ this._ondrop_callback = this.processDrop.bind(this);
- var pos = [e.canvasX,e.canvasY];
- var node = that.graph.getNodeOnPos(pos[0],pos[1]);
- if(!node)
- return;
+ canvas.addEventListener("dragover", this._doNothing, false );
+ canvas.addEventListener("dragend", this._doNothing, false );
+ canvas.addEventListener("drop", this._ondrop_callback, false );
- if(!node.onDropFile)
- return;
+ this._events_binded = true;
+}
- var file = e.dataTransfer.files[0];
- var filename = file.name;
- var ext = LGraphCanvas.getFileExtension( filename );
- //console.log(file);
+LGraphCanvas.prototype.unbindEvents = function()
+{
+ if( !this._events_binded )
+ {
+ console.warn("LGraphCanvas: no events binded");
+ return;
+ }
- //prepare reader
- var reader = new FileReader();
- reader.onload = function (event) {
- //console.log(event.target);
- var data = event.target.result;
- node.onDropFile( data, filename, file );
- };
+ this.canvas.removeEventListener( "mousedown", this._mousedown_callback );
+ this.canvas.removeEventListener( "mousewheel", this._mousewheel_callback );
+ this.canvas.removeEventListener( "DOMMouseScroll", this._mousewheel_callback );
+ this.canvas.removeEventListener( "keydown", this._key_callback );
+ this.canvas.removeEventListener( "keyup", this._key_callback );
+ this.canvas.removeEventListener( "contextmenu", this._doNothing );
+ this.canvas.removeEventListener( "drop", this._ondrop_callback );
- //read data
- var type = file.type.split("/")[0];
- if(type == "text" || type == "")
- reader.readAsText(file);
- else if (type == "image")
- reader.readAsDataURL(file);
- else
- reader.readAsArrayBuffer(file);
+ this.canvas.removeEventListener("touchstart", this.touchHandler );
+ this.canvas.removeEventListener("touchmove", this.touchHandler );
+ this.canvas.removeEventListener("touchend", this.touchHandler );
+ this.canvas.removeEventListener("touchcancel", this.touchHandler );
- return false;
- };
+ this._mousedown_callback = null;
+ this._mousewheel_callback = null;
+ this._key_callback = null;
+ this._ondrop_callback = null;
+
+ this._events_binded = false;
}
LGraphCanvas.getFileExtension = function (url)
@@ -2560,13 +2592,15 @@ LGraphCanvas.prototype.stopRendering = function()
LGraphCanvas.prototype.processMouseDown = function(e)
{
- if(!this.graph) return;
+ if(!this.graph)
+ return;
this.adjustMouseEvent(e);
var ref_window = this.getCanvasWindow();
var document = ref_window.document;
+ //move mouse move event to the window in case it drags outside of the canvas
this.canvas.removeEventListener("mousemove", this._mousemove_callback );
ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
@@ -2792,7 +2826,7 @@ LGraphCanvas.prototype.processMouseMove = function(e)
if(slot != -1 && n.inputs[slot])
{
var slot_type = n.inputs[slot].type;
- if(slot_type == this.connecting_output.type || !slot_type || !this.connecting_output.type )
+ if( !this.connecting_output.type || !slot_type || slot_type.toLowerCase() == this.connecting_output.type.toLowerCase() )
this._highlight_input = pos;
}
else
@@ -2867,11 +2901,13 @@ LGraphCanvas.prototype.processMouseMove = function(e)
LGraphCanvas.prototype.processMouseUp = function(e)
{
- if(!this.graph) return;
+ if(!this.graph)
+ return;
var window = this.getCanvasWindow();
var document = window.document;
+ //restore the mousemove event back to the canvas
document.removeEventListener("mousemove", this._mousemove_callback, true );
this.canvas.addEventListener("mousemove", this._mousemove_callback, true);
document.removeEventListener("mouseup", this._mouseup_callback, true );
@@ -2908,7 +2944,7 @@ LGraphCanvas.prototype.processMouseUp = function(e)
{ //not on top of an input
var input = node.getInputInfo(0);
//simple connect
- if(input && !input.link && input.type == this.connecting_output.type)
+ if(input && !input.link && input.type == this.connecting_output.type) //toLowerCase missing
this.connecting_node.connect(this.connecting_slot, node, 0);
}
}
@@ -2972,75 +3008,11 @@ LGraphCanvas.prototype.processMouseUp = function(e)
return false;
}
-LGraphCanvas.prototype.isOverNodeInput = function(node, canvasx, canvasy, slot_pos)
-{
- if(node.inputs)
- for(var i = 0, l = node.inputs.length; i < l; ++i)
- {
- var input = node.inputs[i];
- var link_pos = node.getConnectionPos(true,i);
- if( isInsideRectangle(canvasx, canvasy, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
- {
- if(slot_pos) { slot_pos[0] = link_pos[0]; slot_pos[1] = link_pos[1] };
- return i;
- }
- }
- return -1;
-}
-
-LGraphCanvas.prototype.processKeyDown = function(e)
-{
- if(!this.graph) return;
- var block_default = false;
-
- //select all Control A
- if(e.keyCode == 65 && e.ctrlKey)
- {
- this.selectAllNodes();
- block_default = true;
- }
-
- //delete or backspace
- if(e.keyCode == 46 || e.keyCode == 8)
- {
- this.deleteSelectedNodes();
- block_default = true;
- }
-
- //collapse
- //...
-
- //TODO
- if(this.selected_nodes)
- for (var i in this.selected_nodes)
- if(this.selected_nodes[i].onKeyDown)
- this.selected_nodes[i].onKeyDown(e);
-
- this.graph.change();
-
- if(block_default)
- {
- e.preventDefault();
- return false;
- }
-}
-
-LGraphCanvas.prototype.processKeyUp = function(e)
-{
- if(!this.graph) return;
- //TODO
- if(this.selected_nodes)
- for (var i in this.selected_nodes)
- if(this.selected_nodes[i].onKeyUp)
- this.selected_nodes[i].onKeyUp(e);
-
- this.graph.change();
-}
LGraphCanvas.prototype.processMouseWheel = function(e)
{
- if(!this.graph) return;
- if(!this.allow_dragcanvas) return;
+ if(!this.graph || !this.allow_dragcanvas)
+ return;
var delta = (e.wheelDeltaY != null ? e.wheelDeltaY : e.detail * -60);
@@ -3066,6 +3038,109 @@ LGraphCanvas.prototype.processMouseWheel = function(e)
return false; // prevent default
}
+LGraphCanvas.prototype.isOverNodeInput = function(node, canvasx, canvasy, slot_pos)
+{
+ if(node.inputs)
+ for(var i = 0, l = node.inputs.length; i < l; ++i)
+ {
+ var input = node.inputs[i];
+ var link_pos = node.getConnectionPos(true,i);
+ if( isInsideRectangle(canvasx, canvasy, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
+ {
+ if(slot_pos) { slot_pos[0] = link_pos[0]; slot_pos[1] = link_pos[1] };
+ return i;
+ }
+ }
+ return -1;
+}
+
+LGraphCanvas.prototype.processKey = function(e)
+{
+ if(!this.graph)
+ return;
+
+ var block_default = false;
+
+ if(e.type == "keydown")
+ {
+ //select all Control A
+ if(e.keyCode == 65 && e.ctrlKey)
+ {
+ this.selectAllNodes();
+ block_default = true;
+ }
+
+ //delete or backspace
+ if(e.keyCode == 46 || e.keyCode == 8)
+ {
+ this.deleteSelectedNodes();
+ block_default = true;
+ }
+
+ //collapse
+ //...
+
+ //TODO
+ if(this.selected_nodes)
+ for (var i in this.selected_nodes)
+ if(this.selected_nodes[i].onKeyDown)
+ this.selected_nodes[i].onKeyDown(e);
+ }
+ else if( e.type == "keyup" )
+ {
+ if(this.selected_nodes)
+ for (var i in this.selected_nodes)
+ if(this.selected_nodes[i].onKeyUp)
+ this.selected_nodes[i].onKeyUp(e);
+ }
+
+ this.graph.change();
+
+ if(block_default)
+ {
+ e.preventDefault();
+ return false;
+ }
+}
+
+LGraphCanvas.prototype.processDrop = function(e)
+{
+ e.preventDefault();
+ this.adjustMouseEvent(e);
+
+ var pos = [e.canvasX,e.canvasY];
+ var node = this.graph.getNodeOnPos(pos[0],pos[1]);
+ if(!node)
+ return;
+
+ if(!node.onDropFile)
+ return;
+
+ var file = e.dataTransfer.files[0];
+ var filename = file.name;
+ var ext = LGraphCanvas.getFileExtension( filename );
+ //console.log(file);
+
+ //prepare reader
+ var reader = new FileReader();
+ reader.onload = function (event) {
+ //console.log(event.target);
+ var data = event.target.result;
+ node.onDropFile( data, filename, file );
+ };
+
+ //read data
+ var type = file.type.split("/")[0];
+ if(type == "text" || type == "")
+ reader.readAsText(file);
+ else if (type == "image")
+ reader.readAsDataURL(file);
+ else
+ reader.readAsArrayBuffer(file);
+
+ return false;
+}
+
LGraphCanvas.prototype.processNodeSelected = function(n,e)
{
n.selected = true;
@@ -3321,7 +3396,8 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
//clear
//canvas.width = canvas.width;
- ctx.clearRect(0,0,canvas.width, canvas.height);
+ if(this.clear_background)
+ ctx.clearRect(0,0,canvas.width, canvas.height);
//draw bg canvas
if(this.bgcanvas == this.canvas)
@@ -3335,19 +3411,7 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
//info widget
if(this.show_info)
- {
- ctx.font = "10px Arial";
- ctx.fillStyle = "#888";
- if(this.graph)
- {
- ctx.fillText( "T: " + this.graph.globaltime.toFixed(2)+"s",5,13*1 );
- ctx.fillText( "I: " + this.graph.iteration,5,13*2 );
- ctx.fillText( "F: " + this.frame,5,13*3 );
- ctx.fillText( "FPS:" + this.fps.toFixed(2),5,13*4 );
- }
- else
- ctx.fillText( "No graph selected",5,13*1 );
- }
+ this.renderInfo(ctx);
if(this.graph)
{
@@ -3422,6 +3486,28 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
this.dirty_canvas = false;
}
+LGraphCanvas.prototype.renderInfo = function( ctx, x, y )
+{
+ x = x || 0;
+ y = y || 0;
+
+ ctx.save();
+ ctx.translate( x, y );
+
+ ctx.font = "10px Arial";
+ ctx.fillStyle = "#888";
+ if(this.graph)
+ {
+ ctx.fillText( "T: " + this.graph.globaltime.toFixed(2)+"s",5,13*1 );
+ ctx.fillText( "I: " + this.graph.iteration,5,13*2 );
+ ctx.fillText( "F: " + this.frame,5,13*3 );
+ ctx.fillText( "FPS:" + this.fps.toFixed(2),5,13*4 );
+ }
+ else
+ ctx.fillText( "No graph selected",5,13*1 );
+ ctx.restore();
+}
+
LGraphCanvas.prototype.drawBackCanvas = function()
{
var canvas = this.bgcanvas;
@@ -3432,7 +3518,8 @@ LGraphCanvas.prototype.drawBackCanvas = function()
ctx.start();
//clear
- ctx.clearRect(0,0,canvas.width, canvas.height);
+ if(this.clear_background)
+ ctx.clearRect(0,0,canvas.width, canvas.height);
//reset in case of error
ctx.restore();
@@ -3633,7 +3720,7 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var slot = node.inputs[i];
ctx.globalAlpha = editor_alpha;
- if (this.connecting_node != null && this.connecting_output.type != 0 && node.inputs[i].type != 0 && this.connecting_output.type != node.inputs[i].type)
+ if (this.connecting_node != null && this.connecting_output.type && node.inputs[i].type && this.connecting_output.type.toLowerCase() != node.inputs[i].type.toLowerCase() )
ctx.globalAlpha = 0.4 * editor_alpha;
ctx.fillStyle = slot.link != null ? "#7F7" : "#AAA";
diff --git a/src/litegraph.js b/src/litegraph.js
index cc4fd136d..dae09ae78 100644
--- a/src/litegraph.js
+++ b/src/litegraph.js
@@ -745,9 +745,10 @@ LGraph.prototype.findNodesByClass = function(classObject)
LGraph.prototype.findNodesByType = function(type)
{
+ var type = type.toLowerCase();
var r = [];
for(var i in this._nodes)
- if(this._nodes[i].type == type)
+ if(this._nodes[i].type.toLowerCase() == type )
r.push(this._nodes[i]);
return r;
}
@@ -851,7 +852,7 @@ LGraph.prototype.changeGlobalInputType = function(name, type)
if(!this.global_inputs[name])
return false;
- if(this.global_inputs[name].type == type)
+ if(this.global_inputs[name].type.toLowerCase() == type.toLowerCase() )
return;
this.global_inputs[name].type = type;
@@ -932,7 +933,7 @@ LGraph.prototype.changeGlobalOutputType = function(name, type)
if(!this.global_outputs[name])
return false;
- if(this.global_outputs[name].type == type)
+ if(this.global_outputs[name].type.toLowerCase() == type.toLowerCase() )
return;
this.global_outputs[name].type = type;
@@ -1724,7 +1725,7 @@ LGraphNode.prototype.connect = function(slot, node, target_slot)
}
else if( !output.type || //generic output
!node.inputs[target_slot].type || //generic input
- output.type == node.inputs[target_slot].type) //same type
+ output.type.toLowerCase() == node.inputs[target_slot].type.toLowerCase() ) //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 ];
@@ -2044,16 +2045,13 @@ LGraphNode.prototype.localToScreen = function(x,y, graphcanvas)
* @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, skip_render)
+function LGraphCanvas( canvas, graph, skip_render )
{
//if(graph === undefined)
// throw ("No graph assigned");
- if(typeof(canvas) == "string")
- canvas = document.querySelector(canvas);
-
- if(!canvas)
- throw("no canvas found");
+ if(canvas && canvas.constructor === String )
+ canvas = document.querySelector( canvas );
this.max_zoom = 10;
this.min_zoom = 0.1;
@@ -2062,7 +2060,7 @@ function LGraphCanvas(canvas, graph, skip_render)
if(graph)
graph.attachCanvas(this);
- this.setCanvas(canvas);
+ this.setCanvas( canvas );
this.clear();
if(!skip_render)
@@ -2097,9 +2095,7 @@ LGraphCanvas.prototype.clear = function()
this.editor_alpha = 1; //used for transition
this.pause_rendering = false;
this.render_shadows = true;
- this.dirty_canvas = true;
- this.dirty_bgcanvas = true;
- this.dirty_area = null;
+ this.clear_background = true;
this.render_only_selected = true;
this.live_mode = false;
@@ -2107,6 +2103,10 @@ LGraphCanvas.prototype.clear = function()
this.allow_dragcanvas = true;
this.allow_dragnodes = true;
+ this.dirty_canvas = true;
+ this.dirty_bgcanvas = true;
+ this.dirty_area = null;
+
this.node_in_panel = null;
this.last_mouse = [0,0];
@@ -2132,10 +2132,13 @@ LGraphCanvas.prototype.clear = function()
* @method setGraph
* @param {LGraph} graph
*/
-LGraphCanvas.prototype.setGraph = function(graph)
+LGraphCanvas.prototype.setGraph = function( graph, skip_clear )
{
- if(this.graph == graph) return;
- this.clear();
+ if(this.graph == graph)
+ return;
+
+ if(!skip_clear)
+ this.clear();
if(!graph && this.graph)
{
@@ -2202,19 +2205,35 @@ LGraphCanvas.prototype.closeSubgraph = function()
* @method setCanvas
* @param {Canvas} assigns a canvas
*/
-LGraphCanvas.prototype.setCanvas = function(canvas)
+LGraphCanvas.prototype.setCanvas = function( canvas, skip_events )
{
var that = this;
- //Canvas association
- if(typeof(canvas) == "string")
- canvas = document.getElementById(canvas);
+ if(canvas)
+ {
+ if( canvas.constructor === String )
+ {
+ canvas = document.getElementById(canvas);
+ if(!canvas)
+ throw("Error creating LiteGraph canvas: Canvas not found");
+ }
+ }
- if(canvas == null)
- throw("Error creating LiteGraph canvas: Canvas not found");
- if(canvas == this.canvas) return;
+ if(canvas === this.canvas)
+ return;
+
+ if(!canvas && this.canvas)
+ {
+ //maybe detach events from old_canvas
+ if(!skip_events)
+ this.unbindEvents();
+ }
this.canvas = canvas;
+
+ if(!canvas)
+ return;
+
//this.canvas.tabindex = "1000";
canvas.className += " lgraphcanvas";
canvas.data = this;
@@ -2244,72 +2263,85 @@ LGraphCanvas.prototype.setCanvas = function(canvas)
this._mousemove_callback = this.processMouseMove.bind(this);
this._mouseup_callback = this.processMouseUp.bind(this);
- canvas.addEventListener("mousedown", this.processMouseDown.bind(this), true ); //down do not need to store the binded
- canvas.addEventListener("mousemove", this._mousemove_callback);
+ if(!skip_events)
+ this.bindEvents();
+}
- canvas.addEventListener("contextmenu", function(e) { e.preventDefault(); return false; });
-
- canvas.addEventListener("mousewheel", this.processMouseWheel.bind(this), false);
- canvas.addEventListener("DOMMouseScroll", this.processMouseWheel.bind(this), false);
+//used in some events to capture them
+LGraphCanvas.prototype._doNothing = function doNothing() { return false; };
+
+LGraphCanvas.prototype.bindEvents = function()
+{
+ if( this._events_binded )
+ {
+ console.warn("LGraphCanvas: events already binded");
+ return;
+ }
+
+ var canvas = this.canvas;
+
+ this._mousedown_callback = this.processMouseDown.bind(this);
+ this._mousewheel_callback = this.processMouseWheel.bind(this);
+
+ canvas.addEventListener("mousedown", this._mousedown_callback, true ); //down do not need to store the binded
+ canvas.addEventListener("mousemove", this._mousemove_callback );
+ canvas.addEventListener("mousewheel", this._mousewheel_callback, false);
+
+ canvas.addEventListener("contextmenu", this._doNothing );
+ canvas.addEventListener("DOMMouseScroll", this._mousewheel_callback, false);
//touch events
//if( 'touchstart' in document.documentElement )
{
- //alert("doo");
canvas.addEventListener("touchstart", this.touchHandler, true);
canvas.addEventListener("touchmove", this.touchHandler, true);
canvas.addEventListener("touchend", this.touchHandler, true);
canvas.addEventListener("touchcancel", this.touchHandler, true);
}
- //this.canvas.onselectstart = function () { return false; };
- canvas.addEventListener("keydown", function(e) {
- that.processKeyDown(e);
- });
+ //Keyboard ******************
+ this._key_callback = this.processKey.bind(this);
- canvas.addEventListener("keyup", function(e) {
- that.processKeyUp(e);
- });
+ canvas.addEventListener("keydown", this._key_callback );
+ canvas.addEventListener("keyup", this._key_callback );
- //droping files
- canvas.ondragover = function () { console.log('hover'); return false; };
- canvas.ondragend = function () { console.log('out'); return false; };
- canvas.ondrop = function (e) {
- e.preventDefault();
- that.adjustMouseEvent(e);
+ //Droping Stuff over nodes ************************************
+ this._ondrop_callback = this.processDrop.bind(this);
- var pos = [e.canvasX,e.canvasY];
- var node = that.graph.getNodeOnPos(pos[0],pos[1]);
- if(!node)
- return;
+ canvas.addEventListener("dragover", this._doNothing, false );
+ canvas.addEventListener("dragend", this._doNothing, false );
+ canvas.addEventListener("drop", this._ondrop_callback, false );
- if(!node.onDropFile)
- return;
+ this._events_binded = true;
+}
- var file = e.dataTransfer.files[0];
- var filename = file.name;
- var ext = LGraphCanvas.getFileExtension( filename );
- //console.log(file);
+LGraphCanvas.prototype.unbindEvents = function()
+{
+ if( !this._events_binded )
+ {
+ console.warn("LGraphCanvas: no events binded");
+ return;
+ }
- //prepare reader
- var reader = new FileReader();
- reader.onload = function (event) {
- //console.log(event.target);
- var data = event.target.result;
- node.onDropFile( data, filename, file );
- };
+ this.canvas.removeEventListener( "mousedown", this._mousedown_callback );
+ this.canvas.removeEventListener( "mousewheel", this._mousewheel_callback );
+ this.canvas.removeEventListener( "DOMMouseScroll", this._mousewheel_callback );
+ this.canvas.removeEventListener( "keydown", this._key_callback );
+ this.canvas.removeEventListener( "keyup", this._key_callback );
+ this.canvas.removeEventListener( "contextmenu", this._doNothing );
+ this.canvas.removeEventListener( "drop", this._ondrop_callback );
- //read data
- var type = file.type.split("/")[0];
- if(type == "text" || type == "")
- reader.readAsText(file);
- else if (type == "image")
- reader.readAsDataURL(file);
- else
- reader.readAsArrayBuffer(file);
+ this.canvas.removeEventListener("touchstart", this.touchHandler );
+ this.canvas.removeEventListener("touchmove", this.touchHandler );
+ this.canvas.removeEventListener("touchend", this.touchHandler );
+ this.canvas.removeEventListener("touchcancel", this.touchHandler );
- return false;
- };
+ this._mousedown_callback = null;
+ this._mousewheel_callback = null;
+ this._key_callback = null;
+ this._ondrop_callback = null;
+
+ this._events_binded = false;
}
LGraphCanvas.getFileExtension = function (url)
@@ -2466,13 +2498,15 @@ LGraphCanvas.prototype.stopRendering = function()
LGraphCanvas.prototype.processMouseDown = function(e)
{
- if(!this.graph) return;
+ if(!this.graph)
+ return;
this.adjustMouseEvent(e);
var ref_window = this.getCanvasWindow();
var document = ref_window.document;
+ //move mouse move event to the window in case it drags outside of the canvas
this.canvas.removeEventListener("mousemove", this._mousemove_callback );
ref_window.document.addEventListener("mousemove", this._mousemove_callback, true ); //catch for the entire window
ref_window.document.addEventListener("mouseup", this._mouseup_callback, true );
@@ -2698,7 +2732,7 @@ LGraphCanvas.prototype.processMouseMove = function(e)
if(slot != -1 && n.inputs[slot])
{
var slot_type = n.inputs[slot].type;
- if(slot_type == this.connecting_output.type || !slot_type || !this.connecting_output.type )
+ if( !this.connecting_output.type || !slot_type || slot_type.toLowerCase() == this.connecting_output.type.toLowerCase() )
this._highlight_input = pos;
}
else
@@ -2773,11 +2807,13 @@ LGraphCanvas.prototype.processMouseMove = function(e)
LGraphCanvas.prototype.processMouseUp = function(e)
{
- if(!this.graph) return;
+ if(!this.graph)
+ return;
var window = this.getCanvasWindow();
var document = window.document;
+ //restore the mousemove event back to the canvas
document.removeEventListener("mousemove", this._mousemove_callback, true );
this.canvas.addEventListener("mousemove", this._mousemove_callback, true);
document.removeEventListener("mouseup", this._mouseup_callback, true );
@@ -2814,7 +2850,7 @@ LGraphCanvas.prototype.processMouseUp = function(e)
{ //not on top of an input
var input = node.getInputInfo(0);
//simple connect
- if(input && !input.link && input.type == this.connecting_output.type)
+ if(input && !input.link && input.type == this.connecting_output.type) //toLowerCase missing
this.connecting_node.connect(this.connecting_slot, node, 0);
}
}
@@ -2878,75 +2914,11 @@ LGraphCanvas.prototype.processMouseUp = function(e)
return false;
}
-LGraphCanvas.prototype.isOverNodeInput = function(node, canvasx, canvasy, slot_pos)
-{
- if(node.inputs)
- for(var i = 0, l = node.inputs.length; i < l; ++i)
- {
- var input = node.inputs[i];
- var link_pos = node.getConnectionPos(true,i);
- if( isInsideRectangle(canvasx, canvasy, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
- {
- if(slot_pos) { slot_pos[0] = link_pos[0]; slot_pos[1] = link_pos[1] };
- return i;
- }
- }
- return -1;
-}
-
-LGraphCanvas.prototype.processKeyDown = function(e)
-{
- if(!this.graph) return;
- var block_default = false;
-
- //select all Control A
- if(e.keyCode == 65 && e.ctrlKey)
- {
- this.selectAllNodes();
- block_default = true;
- }
-
- //delete or backspace
- if(e.keyCode == 46 || e.keyCode == 8)
- {
- this.deleteSelectedNodes();
- block_default = true;
- }
-
- //collapse
- //...
-
- //TODO
- if(this.selected_nodes)
- for (var i in this.selected_nodes)
- if(this.selected_nodes[i].onKeyDown)
- this.selected_nodes[i].onKeyDown(e);
-
- this.graph.change();
-
- if(block_default)
- {
- e.preventDefault();
- return false;
- }
-}
-
-LGraphCanvas.prototype.processKeyUp = function(e)
-{
- if(!this.graph) return;
- //TODO
- if(this.selected_nodes)
- for (var i in this.selected_nodes)
- if(this.selected_nodes[i].onKeyUp)
- this.selected_nodes[i].onKeyUp(e);
-
- this.graph.change();
-}
LGraphCanvas.prototype.processMouseWheel = function(e)
{
- if(!this.graph) return;
- if(!this.allow_dragcanvas) return;
+ if(!this.graph || !this.allow_dragcanvas)
+ return;
var delta = (e.wheelDeltaY != null ? e.wheelDeltaY : e.detail * -60);
@@ -2972,6 +2944,109 @@ LGraphCanvas.prototype.processMouseWheel = function(e)
return false; // prevent default
}
+LGraphCanvas.prototype.isOverNodeInput = function(node, canvasx, canvasy, slot_pos)
+{
+ if(node.inputs)
+ for(var i = 0, l = node.inputs.length; i < l; ++i)
+ {
+ var input = node.inputs[i];
+ var link_pos = node.getConnectionPos(true,i);
+ if( isInsideRectangle(canvasx, canvasy, link_pos[0] - 10, link_pos[1] - 5, 20,10) )
+ {
+ if(slot_pos) { slot_pos[0] = link_pos[0]; slot_pos[1] = link_pos[1] };
+ return i;
+ }
+ }
+ return -1;
+}
+
+LGraphCanvas.prototype.processKey = function(e)
+{
+ if(!this.graph)
+ return;
+
+ var block_default = false;
+
+ if(e.type == "keydown")
+ {
+ //select all Control A
+ if(e.keyCode == 65 && e.ctrlKey)
+ {
+ this.selectAllNodes();
+ block_default = true;
+ }
+
+ //delete or backspace
+ if(e.keyCode == 46 || e.keyCode == 8)
+ {
+ this.deleteSelectedNodes();
+ block_default = true;
+ }
+
+ //collapse
+ //...
+
+ //TODO
+ if(this.selected_nodes)
+ for (var i in this.selected_nodes)
+ if(this.selected_nodes[i].onKeyDown)
+ this.selected_nodes[i].onKeyDown(e);
+ }
+ else if( e.type == "keyup" )
+ {
+ if(this.selected_nodes)
+ for (var i in this.selected_nodes)
+ if(this.selected_nodes[i].onKeyUp)
+ this.selected_nodes[i].onKeyUp(e);
+ }
+
+ this.graph.change();
+
+ if(block_default)
+ {
+ e.preventDefault();
+ return false;
+ }
+}
+
+LGraphCanvas.prototype.processDrop = function(e)
+{
+ e.preventDefault();
+ this.adjustMouseEvent(e);
+
+ var pos = [e.canvasX,e.canvasY];
+ var node = this.graph.getNodeOnPos(pos[0],pos[1]);
+ if(!node)
+ return;
+
+ if(!node.onDropFile)
+ return;
+
+ var file = e.dataTransfer.files[0];
+ var filename = file.name;
+ var ext = LGraphCanvas.getFileExtension( filename );
+ //console.log(file);
+
+ //prepare reader
+ var reader = new FileReader();
+ reader.onload = function (event) {
+ //console.log(event.target);
+ var data = event.target.result;
+ node.onDropFile( data, filename, file );
+ };
+
+ //read data
+ var type = file.type.split("/")[0];
+ if(type == "text" || type == "")
+ reader.readAsText(file);
+ else if (type == "image")
+ reader.readAsDataURL(file);
+ else
+ reader.readAsArrayBuffer(file);
+
+ return false;
+}
+
LGraphCanvas.prototype.processNodeSelected = function(n,e)
{
n.selected = true;
@@ -3227,7 +3302,8 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
//clear
//canvas.width = canvas.width;
- ctx.clearRect(0,0,canvas.width, canvas.height);
+ if(this.clear_background)
+ ctx.clearRect(0,0,canvas.width, canvas.height);
//draw bg canvas
if(this.bgcanvas == this.canvas)
@@ -3241,19 +3317,7 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
//info widget
if(this.show_info)
- {
- ctx.font = "10px Arial";
- ctx.fillStyle = "#888";
- if(this.graph)
- {
- ctx.fillText( "T: " + this.graph.globaltime.toFixed(2)+"s",5,13*1 );
- ctx.fillText( "I: " + this.graph.iteration,5,13*2 );
- ctx.fillText( "F: " + this.frame,5,13*3 );
- ctx.fillText( "FPS:" + this.fps.toFixed(2),5,13*4 );
- }
- else
- ctx.fillText( "No graph selected",5,13*1 );
- }
+ this.renderInfo(ctx);
if(this.graph)
{
@@ -3328,6 +3392,28 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
this.dirty_canvas = false;
}
+LGraphCanvas.prototype.renderInfo = function( ctx, x, y )
+{
+ x = x || 0;
+ y = y || 0;
+
+ ctx.save();
+ ctx.translate( x, y );
+
+ ctx.font = "10px Arial";
+ ctx.fillStyle = "#888";
+ if(this.graph)
+ {
+ ctx.fillText( "T: " + this.graph.globaltime.toFixed(2)+"s",5,13*1 );
+ ctx.fillText( "I: " + this.graph.iteration,5,13*2 );
+ ctx.fillText( "F: " + this.frame,5,13*3 );
+ ctx.fillText( "FPS:" + this.fps.toFixed(2),5,13*4 );
+ }
+ else
+ ctx.fillText( "No graph selected",5,13*1 );
+ ctx.restore();
+}
+
LGraphCanvas.prototype.drawBackCanvas = function()
{
var canvas = this.bgcanvas;
@@ -3338,7 +3424,8 @@ LGraphCanvas.prototype.drawBackCanvas = function()
ctx.start();
//clear
- ctx.clearRect(0,0,canvas.width, canvas.height);
+ if(this.clear_background)
+ ctx.clearRect(0,0,canvas.width, canvas.height);
//reset in case of error
ctx.restore();
@@ -3539,7 +3626,7 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var slot = node.inputs[i];
ctx.globalAlpha = editor_alpha;
- if (this.connecting_node != null && this.connecting_output.type != 0 && node.inputs[i].type != 0 && this.connecting_output.type != node.inputs[i].type)
+ if (this.connecting_node != null && this.connecting_output.type && node.inputs[i].type && this.connecting_output.type.toLowerCase() != node.inputs[i].type.toLowerCase() )
ctx.globalAlpha = 0.4 * editor_alpha;
ctx.fillStyle = slot.link != null ? "#7F7" : "#AAA";
diff --git a/src/nodes/base.js b/src/nodes/base.js
index c87513167..0e186698d 100644
--- a/src/nodes/base.js
+++ b/src/nodes/base.js
@@ -138,7 +138,7 @@ Subgraph.prototype.clone = function()
}
-LiteGraph.registerNodeType("graph/subgraph", Subgraph);
+LiteGraph.registerNodeType("graph/subgraph", Subgraph );
//Input for a subgraph
diff --git a/src/nodes/input.js b/src/nodes/input.js
new file mode 100644
index 000000000..92e55436d
--- /dev/null
+++ b/src/nodes/input.js
@@ -0,0 +1,132 @@
+(function(){
+
+function GamepadInput()
+{
+ this.addOutput("left_x_axis","number");
+ this.addOutput("left_y_axis","number");
+ this.properties = {};
+}
+
+GamepadInput.title = "Gamepad";
+GamepadInput.desc = "gets the input of the gamepad";
+
+GamepadInput.prototype.onExecute = function()
+{
+ //get gamepad
+ var gamepad = this.getGamepad();
+ if(!gamepad)
+ return;
+
+ if(this.outputs)
+ {
+ for(var i = 0; i < this.outputs.length; i++)
+ {
+ var output = this.outputs[i];
+ var v = null;
+ switch( output.name )
+ {
+ case "left_x_axis": v = gamepad.xbox.axes["lx"]; break;
+ case "left_y_axis": v = gamepad.xbox.axes["ly"]; break;
+ case "right_x_axis": v = gamepad.xbox.axes["rx"]; break;
+ case "right_y_axis": v = gamepad.xbox.axes["ry"]; break;
+ case "a_button": v = gamepad.xbox.buttons["a"] ? 1 : 0; break;
+ case "b_button": v = gamepad.xbox.buttons["b"] ? 1 : 0; break;
+ case "x_button": v = gamepad.xbox.buttons["x"] ? 1 : 0; break;
+ case "y_button": v = gamepad.xbox.buttons["y"] ? 1 : 0; break;
+ case "lb_button": v = gamepad.xbox.buttons["lb"] ? 1 : 0; break;
+ case "rb_button": v = gamepad.xbox.buttons["rb"] ? 1 : 0; break;
+ case "ls_button": v = gamepad.xbox.buttons["ls"] ? 1 : 0; break;
+ case "rs_button": v = gamepad.xbox.buttons["rs"] ? 1 : 0; break;
+ case "start_button": v = gamepad.xbox.buttons["start"] ? 1 : 0; break;
+ case "back_button": v = gamepad.xbox.buttons["back"] ? 1 : 0; break;
+ default: break;
+ }
+ this.setOutputData(i,v);
+ }
+ }
+}
+
+GamepadInput.prototype.getGamepad = function()
+{
+ var getGamepads = navigator.getGamepads || navigator.webkitGetGamepads || navigator.mozGetGamepads;
+ if(!getGamepads)
+ return null;
+ var gamepads = getGamepads.call(navigator);
+ var gamepad = null;
+
+ for(var i = 0; i < 4; i++)
+ {
+ if (gamepads[i])
+ {
+ gamepad = gamepads[i];
+
+ //xbox controller mapping
+ var xbox = this.xbox_mapping;
+ if(!xbox)
+ xbox = this.xbox_mapping = { axes:[], buttons:{}, hat: ""};
+
+ xbox.axes["lx"] = gamepad.axes[0];
+ xbox.axes["ly"] = gamepad.axes[1];
+ xbox.axes["rx"] = gamepad.axes[2];
+ xbox.axes["ry"] = gamepad.axes[3];
+ xbox.axes["triggers"] = gamepad.axes[4];
+
+ for(var i = 0; i < gamepad.buttons.length; i++)
+ {
+ //mapping of XBOX
+ switch(i) //I use a switch to ensure that a player with another gamepad could play
+ {
+ case 0: xbox.buttons["a"] = gamepad.buttons[i].pressed; break;
+ case 1: xbox.buttons["b"] = gamepad.buttons[i].pressed; break;
+ case 2: xbox.buttons["x"] = gamepad.buttons[i].pressed; break;
+ case 3: xbox.buttons["y"] = gamepad.buttons[i].pressed; break;
+ case 4: xbox.buttons["lb"] = gamepad.buttons[i].pressed; break;
+ case 5: xbox.buttons["rb"] = gamepad.buttons[i].pressed; break;
+ case 6: xbox.buttons["lt"] = gamepad.buttons[i].pressed; break;
+ case 7: xbox.buttons["rt"] = gamepad.buttons[i].pressed; break;
+ case 8: xbox.buttons["back"] = gamepad.buttons[i].pressed; break;
+ case 9: xbox.buttons["start"] = gamepad.buttons[i].pressed; break;
+ case 10: xbox.buttons["ls"] = gamepad.buttons[i].pressed; break;
+ case 11: xbox.buttons["rs"] = gamepad.buttons[i].pressed; break;
+ case 12: if( gamepad.buttons[i].pressed) xbox.hat += "up"; break;
+ case 13: if( gamepad.buttons[i].pressed) xbox.hat += "down"; break;
+ case 14: if( gamepad.buttons[i].pressed) xbox.hat += "left"; break;
+ case 15: if( gamepad.buttons[i].pressed) xbox.hat += "right"; break;
+ case 16: xbox.buttons["home"] = gamepad.buttons[i].pressed; break;
+ default:
+ }
+ }
+ gamepad.xbox = xbox;
+ return gamepad;
+ }
+ }
+}
+
+GamepadInput.prototype.onDrawBackground = function(ctx)
+{
+ //render
+}
+
+GamepadInput.prototype.onGetOutputs = function() {
+ return [
+ ["left_x_axis","number"],
+ ["left_y_axis","number"],
+ ["right_x_axis","number"],
+ ["right_y_axis","number"],
+ ["trigger","number"],
+ ["a_button","number"],
+ ["b_button","number"],
+ ["x_button","number"],
+ ["y_button","number"],
+ ["lb_button","number"],
+ ["rb_button","number"],
+ ["ls_button","number"],
+ ["rs_button","number"],
+ ["start","number"],
+ ["back","number"]
+ ];
+}
+
+LiteGraph.registerNodeType("input/gamepad", GamepadInput );
+
+})();
\ No newline at end of file
diff --git a/utils/deploy_files.txt b/utils/deploy_files.txt
index 65cb39dd1..54e252603 100644
--- a/utils/deploy_files.txt
+++ b/utils/deploy_files.txt
@@ -1,6 +1,7 @@
../src/litegraph.js
../src/nodes/base.js
../src/nodes/interface.js
+../src/nodes/input.js
../src/nodes/math.js
../src/nodes/logic.js
../src/nodes/image.js