diff --git a/src/litegraph.js b/src/litegraph.js index 359f6e1d0..a9dcac594 100755 --- a/src/litegraph.js +++ b/src/litegraph.js @@ -1,5 +1,4 @@ - -(function(global) { +(function (global) { // ************************************************************* // LiteGraph CLASS ******* // ************************************************************* @@ -66,7 +65,7 @@ ACTION: -1, //for inputs NODE_MODES: ["Always", "On Event", "Never", "On Trigger"], // helper, will add "On Request" and more in the future - NODE_MODES_COLORS:["#666","#422","#333","#224","#626"], // use with node_box_coloured_by_mode + NODE_MODES_COLORS: ["#666", "#422", "#333", "#224", "#626"], // use with node_box_coloured_by_mode ALWAYS: 0, ON_EVENT: 1, NEVER: 2, @@ -100,44 +99,44 @@ registered_node_types: {}, //nodetypes by string node_types_by_file_extension: {}, //used for dropping files in the canvas Nodes: {}, //node types by classname - Globals: {}, //used to store vars between graphs + Globals: {}, //used to store vars between graphs searchbox_extras: {}, //used to add extra features to the search box auto_sort_node_types: false, // [true!] If set to true, will automatically sort node types / categories in the context menus - - node_box_coloured_when_on: false, // [true!] this make the nodes box (top left circle) coloured when triggered (execute/action), visual feedback + + node_box_coloured_when_on: false, // [true!] this make the nodes box (top left circle) coloured when triggered (execute/action), visual feedback node_box_coloured_by_mode: false, // [true!] nodebox based on node mode, visual feedback - + dialog_close_on_mouse_leave: true, // [false on mobile] better true if not touch device, TODO add an helper/listener to close if false dialog_close_on_mouse_leave_delay: 500, - + shift_click_do_break_link_from: false, // [false!] prefer false if results too easy to break links - implement with ALT or TODO custom keys click_do_break_link_to: false, // [false!]prefer false, way too easy to break links - + search_hide_on_mouse_leave: true, // [false on mobile] better true if not touch device, TODO add an helper/listener to close if false search_filter_enabled: false, // [true!] enable filtering slots type in the search widget, !requires auto_load_slot_types or manual set registered_slot_[in/out]_types and slot_types_[in/out] search_show_all_on_open: true, // [true!] opens the results list when opening the search widget - + auto_load_slot_types: false, // [if want false, use true, run, get vars values to be statically set, than disable] nodes types and nodeclass association with node types need to be calculated, if dont want this, calculate once and set registered_slot_[in/out]_types and slot_types_[in/out] - - // set these values if not using auto_load_slot_types + + // set these values if not using auto_load_slot_types registered_slot_in_types: {}, // slot types for nodeclass registered_slot_out_types: {}, // slot types for nodeclass slot_types_in: [], // slot types IN slot_types_out: [], // slot types OUT slot_types_default_in: [], // specify for each IN slot type a(/many) default node(s), use single string, array, or object (with node, title, parameters, ..) like for search - slot_types_default_out: [], // specify for each OUT slot type a(/many) default node(s), use single string, array, or object (with node, title, parameters, ..) like for search - - alt_drag_do_clone_nodes: false, // [true!] very handy, ALT click to clone and drag the new node - - do_add_triggers_slots: false, // [true!] will create and connect event slots when using action/events connections, !WILL CHANGE node mode when using onTrigger (enable mode colors), onExecuted does not need this - - allow_multi_output_for_events: true, // [false!] being events, it is strongly reccomended to use them sequentially, one by one - - middle_click_slot_add_default_node: false, //[true!] allows to create and connect a ndoe clicking with the third button (wheel) - - release_link_on_empty_shows_menu: false, //[true!] dragging a link to empty space will open a menu, add from list, search or defaults - + slot_types_default_out: [], // specify for each OUT slot type a(/many) default node(s), use single string, array, or object (with node, title, parameters, ..) like for search + + alt_drag_do_clone_nodes: false, // [true!] very handy, ALT click to clone and drag the new node + + do_add_triggers_slots: false, // [true!] will create and connect event slots when using action/events connections, !WILL CHANGE node mode when using onTrigger (enable mode colors), onExecuted does not need this + + allow_multi_output_for_events: true, // [false!] being events, it is strongly reccomended to use them sequentially, one by one + + middle_click_slot_add_default_node: false, //[true!] allows to create and connect a ndoe clicking with the third button (wheel) + + release_link_on_empty_shows_menu: false, //[true!] dragging a link to empty space will open a menu, add from list, search or defaults + pointerevents_method: "mouse", // "mouse"|"pointer" use mouse for retrocompatibility issues? (none found @ now) // TODO implement pointercancel, gotpointercapture, lostpointercapture, (pointerover, pointerout if necessary) @@ -154,7 +153,7 @@ * @param {Class} base_class class containing the structure of a node */ - registerNodeType: function(type, base_class) { + registerNodeType: function (type, base_class) { if (!base_class.prototype) { throw "Cannot register a simple object, it must be a class with a prototype"; } @@ -181,12 +180,17 @@ } const prev = this.registered_node_types[type]; - if(prev) { + if (prev) { console.log("replacing node type: " + type); } - if( !Object.prototype.hasOwnProperty.call( base_class.prototype, "shape") ) { + if ( + !Object.prototype.hasOwnProperty.call( + base_class.prototype, + "shape" + ) + ) { Object.defineProperty(base_class.prototype, "shape", { - set: function(v) { + set: function (v) { switch (v) { case "default": delete this._shape; @@ -207,20 +211,21 @@ this._shape = v; } }, - get: function() { + get: function () { return this._shape; }, enumerable: true, - configurable: true + configurable: true, }); - //used to know which nodes to create when dragging files to the canvas if (base_class.supported_extensions) { for (let i in base_class.supported_extensions) { const ext = base_class.supported_extensions[i]; - if(ext && ext.constructor === String) { - this.node_types_by_file_extension[ ext.toLowerCase() ] = base_class; + if (ext && ext.constructor === String) { + this.node_types_by_file_extension[ + ext.toLowerCase() + ] = base_class; } } } @@ -245,7 +250,7 @@ " has onPropertyChange method, it must be called onPropertyChanged with d at the end" ); } - + // TODO one would want to know input and ouput :: this would allow through registerNodeAndSlotType to get all the slots types if (this.auto_load_slot_types) { new base_class(base_class.title || "tmpnode"); @@ -257,7 +262,7 @@ * @method unregisterNodeType * @param {String|Object} type name of the node or the node constructor itself */ - unregisterNodeType: function(type) { + unregisterNodeType: function (type) { const base_class = type.constructor === String ? this.registered_node_types[type] @@ -272,12 +277,12 @@ }, /** - * Save a slot type and his node - * @method registerSlotType - * @param {String|Object} type name of the node or the node constructor itself - * @param {String} slot_type name of the slot type (variable type), eg. string, number, array, boolean, .. - */ - registerNodeAndSlotType: function(type, slot_type, out){ + * Save a slot type and his node + * @method registerSlotType + * @param {String|Object} type name of the node or the node constructor itself + * @param {String} slot_type name of the slot type (variable type), eg. string, number, array, boolean, .. + */ + registerNodeAndSlotType: function (type, slot_type, out) { out = out || false; const base_class = type.constructor === String && @@ -325,7 +330,7 @@ } } }, - + /** * Create a new nodetype by passing an object with some properties * like onCreate, inputs:Array, outputs:Array, properties, onExecute @@ -333,48 +338,45 @@ * @param {String} name node name with namespace (p.e.: 'math/sum') * @param {Object} object methods expected onCreate, inputs, outputs, properties, onExecute */ - buildNodeClassFromObject: function( - name, - object - ) { + buildNodeClassFromObject: function (name, object) { var ctor_code = ""; - if(object.inputs) - for(var i=0; i < object.inputs.length; ++i) - { - var _name = object.inputs[i][0]; - var _type = object.inputs[i][1]; - if(_type && _type.constructor === String) - _type = '"'+_type+'"'; - ctor_code += "this.addInput('"+_name+"',"+_type+");\n"; - } - if(object.outputs) - for(var i=0; i < object.outputs.length; ++i) - { - var _name = object.outputs[i][0]; - var _type = object.outputs[i][1]; - if(_type && _type.constructor === String) - _type = '"'+_type+'"'; - ctor_code += "this.addOutput('"+_name+"',"+_type+");\n"; - } - if(object.properties) - for(var i in object.properties) - { - var prop = object.properties[i]; - if(prop && prop.constructor === String) - prop = '"'+prop+'"'; - ctor_code += "this.addProperty('"+i+"',"+prop+");\n"; - } + if (object.inputs) + for (var i = 0; i < object.inputs.length; ++i) { + var _name = object.inputs[i][0]; + var _type = object.inputs[i][1]; + if (_type && _type.constructor === String) + _type = '"' + _type + '"'; + ctor_code += + "this.addInput('" + _name + "'," + _type + ");\n"; + } + if (object.outputs) + for (var i = 0; i < object.outputs.length; ++i) { + var _name = object.outputs[i][0]; + var _type = object.outputs[i][1]; + if (_type && _type.constructor === String) + _type = '"' + _type + '"'; + ctor_code += + "this.addOutput('" + _name + "'," + _type + ");\n"; + } + if (object.properties) + for (var i in object.properties) { + var prop = object.properties[i]; + if (prop && prop.constructor === String) + prop = '"' + prop + '"'; + ctor_code += + "this.addProperty('" + i + "'," + prop + ");\n"; + } ctor_code += "if(this.onCreate)this.onCreate()"; var classobj = Function(ctor_code); - for(var i in object) - if(i!="inputs" && i!="outputs" && i!="properties") + for (var i in object) + if (i != "inputs" && i != "outputs" && i != "properties") classobj.prototype[i] = object[i]; classobj.title = object.title || name.split("/").pop(); classobj.desc = object.desc || "Generated from object"; this.registerNodeType(name, classobj); return classobj; }, - + /** * Create a new nodetype by passing a function, it wraps it with a proper class and generates inputs according to the parameters of the function. * Useful to wrap simple methods that do not require properties, and that only process some input to generate an output. @@ -385,7 +387,7 @@ * @param {String} return_type [optional] string with the return type, otherwise it will be generic * @param {Object} properties [optional] properties to be configurable */ - wrapFunctionAsNode: function( + wrapFunctionAsNode: function ( name, func, param_types, @@ -394,32 +396,33 @@ ) { var params = Array(func.length); var code = ""; - if(param_types !== null) //null means no inputs - { + if (param_types !== null) { + //null means no inputs var names = LiteGraph.getParameterNames(func); for (var i = 0; i < names.length; ++i) { var type = 0; - if(param_types) - { + if (param_types) { //type = param_types[i] != null ? "'" + param_types[i] + "'" : "0"; - if( param_types[i] != null && param_types[i].constructor === String ) - type = "'" + param_types[i] + "'" ; - else if( param_types[i] != null ) - type = param_types[i]; - } - code += - "this.addInput('" + - names[i] + - "'," + - type + - ");\n"; + if ( + param_types[i] != null && + param_types[i].constructor === String + ) + type = "'" + param_types[i] + "'"; + else if (param_types[i] != null) type = param_types[i]; + } + code += "this.addInput('" + names[i] + "'," + type + ");\n"; } } - if(return_type !== null) //null means no output - code += - "this.addOutput('out'," + - (return_type != null ? (return_type.constructor === String ? "'" + return_type + "'" : return_type) : 0) + - ");\n"; + if (return_type !== null) + //null means no output + code += + "this.addOutput('out'," + + (return_type != null + ? return_type.constructor === String + ? "'" + return_type + "'" + : return_type + : 0) + + ");\n"; if (properties) { code += "this.properties = " + JSON.stringify(properties) + ";\n"; @@ -441,7 +444,7 @@ /** * Removes all previously registered node's types */ - clearRegisteredTypes: function() { + clearRegisteredTypes: function () { this.registered_node_types = {}; this.node_types_by_file_extension = {}; this.Nodes = {}; @@ -454,7 +457,7 @@ * @method addNodeMethod * @param {Function} func */ - addNodeMethod: function(name, func) { + addNodeMethod: function (name, func) { LGraphNode.prototype[name] = func; for (var i in this.registered_node_types) { var type = this.registered_node_types[i]; @@ -473,7 +476,7 @@ * @param {Object} options to set options */ - createNode: function(type, title, options) { + createNode: function (type, title, options) { var base_class = this.registered_node_types[type]; if (!base_class) { if (LiteGraph.debug) { @@ -517,7 +520,7 @@ } if (!node.size) { node.size = node.computeSize(); - //call onresize? + //call onresize? } if (!node.pos) { node.pos = LiteGraph.DEFAULT_POSITION.concat(); @@ -533,11 +536,11 @@ } } - // callback - if ( node.onNodeCreated ) { + // callback + if (node.onNodeCreated) { node.onNodeCreated(); } - + return node; }, @@ -547,7 +550,7 @@ * @param {String} type full name of the node class. p.e. "math/sin" * @return {Class} the node class */ - getNodeType: function(type) { + getNodeType: function (type) { return this.registered_node_types[type]; }, @@ -558,7 +561,7 @@ * @return {Array} array with all the node classes */ - getNodeTypesInCategory: function(category, filter) { + getNodeTypesInCategory: function (category, filter) { var r = []; for (var i in this.registered_node_types) { var type = this.registered_node_types[i]; @@ -576,7 +579,9 @@ } if (this.auto_sort_node_types) { - r.sort(function(a,b){return a.title.localeCompare(b.title)}); + r.sort(function (a, b) { + return a.title.localeCompare(b.title); + }); } return r; @@ -588,14 +593,12 @@ * @param {String} filter only nodes with ctor.filter equal can be shown * @return {Array} array with all the names of the categories */ - getNodeTypesCategories: function( filter ) { + getNodeTypesCategories: function (filter) { var categories = { "": 1 }; for (var i in this.registered_node_types) { - var type = this.registered_node_types[i]; - if ( type.category && !type.skip_list ) - { - if(type.filter != filter) - continue; + var type = this.registered_node_types[i]; + if (type.category && !type.skip_list) { + if (type.filter != filter) continue; categories[type.category] = 1; } } @@ -607,18 +610,18 @@ }, //debug purposes: reloads all the js scripts that matches a wildcard - reloadNodes: function(folder_wildcard) { + reloadNodes: function (folder_wildcard) { var tmp = document.getElementsByTagName("script"); //weird, this array changes by its own, so we use a copy var script_files = []; - for (var i=0; i < tmp.length; i++) { + for (var i = 0; i < tmp.length; i++) { script_files.push(tmp[i]); } var docHeadObj = document.getElementsByTagName("head")[0]; folder_wildcard = document.location.href + folder_wildcard; - for (var i=0; i < script_files.length; i++) { + for (var i = 0; i < script_files.length; i++) { var src = script_files[i].src; if ( !src || @@ -652,7 +655,7 @@ }, //separated just to improve if it doesn't work - cloneObject: function(obj, target) { + cloneObject: function (obj, target) { if (obj == null) { return null; } @@ -670,8 +673,10 @@ /* * https://gist.github.com/jed/982883?permalink_comment_id=852670#gistcomment-852670 */ - uuidv4: function() { - return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,a=>(a^Math.random()*16>>a/4).toString(16)); + uuidv4: function () { + return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (a) => + (a ^ ((Math.random() * 16) >> (a / 4))).toString(16) + ); }, /** @@ -681,14 +686,14 @@ * @param {String} type_b * @return {Boolean} true if they can be connected */ - isValidConnection: function(type_a, type_b) { - if (type_a=="" || type_a==="*") type_a = 0; - if (type_b=="" || type_b==="*") type_b = 0; + isValidConnection: function (type_a, type_b) { + if (type_a == "" || type_a === "*") type_a = 0; + if (type_b == "" || type_b === "*") type_b = 0; if ( - !type_a //generic output - || !type_b // generic input - || type_a == type_b //same type (is valid for triggers) - || (type_a == LiteGraph.EVENT && type_b == LiteGraph.ACTION) + !type_a || //generic output + !type_b || // generic input + type_a == type_b || //same type (is valid for triggers) + (type_a == LiteGraph.EVENT && type_b == LiteGraph.ACTION) ) { return true; } @@ -709,8 +714,13 @@ var supported_types_b = type_b.split(","); for (var i = 0; i < supported_types_a.length; ++i) { for (var j = 0; j < supported_types_b.length; ++j) { - if(this.isValidConnection(supported_types_a[i],supported_types_b[j])){ - //if (supported_types_a[i] == supported_types_b[j]) { + if ( + this.isValidConnection( + supported_types_a[i], + supported_types_b[j] + ) + ) { + //if (supported_types_a[i] == supported_types_b[j]) { return true; } } @@ -727,11 +737,11 @@ * @param {Object} data it could contain info of how the node should be configured * @return {Boolean} true if they can be connected */ - registerSearchboxExtra: function(node_type, description, data) { + registerSearchboxExtra: function (node_type, description, data) { this.searchbox_extras[description.toLowerCase()] = { type: node_type, desc: description, - data: data + data: data, }; }, @@ -742,62 +752,48 @@ * @param {String} type an string to know how to fetch it: "text","arraybuffer","json","blob" * @param {Function} on_complete callback(data) * @param {Function} on_error in case of an error - * @return {FileReader|Promise} returns the object used to + * @return {FileReader|Promise} returns the object used to */ - fetchFile: function( url, type, on_complete, on_error ) { - var that = this; - if(!url) - return null; - - type = type || "text"; - if( url.constructor === String ) - { - if (url.substr(0, 4) == "http" && LiteGraph.proxy) { - url = LiteGraph.proxy + url.substr(url.indexOf(":") + 3); - } - return fetch(url) - .then(function(response) { - if(!response.ok) - throw new Error("File not found"); //it will be catch below - if(type == "arraybuffer") - return response.arrayBuffer(); - else if(type == "text" || type == "string") - return response.text(); - else if(type == "json") - return response.json(); - else if(type == "blob") - return response.blob(); - }) - .then(function(data) { - if(on_complete) - on_complete(data); - }) - .catch(function(error) { - console.error("error fetching file:",url); - if(on_error) - on_error(error); - }); - } - else if( url.constructor === File || url.constructor === Blob) - { - var reader = new FileReader(); - reader.onload = function(e) - { - var v = e.target.result; - if( type == "json" ) - v = JSON.parse(v); - if(on_complete) - on_complete(v); - } - if(type == "arraybuffer") - return reader.readAsArrayBuffer(url); - else if(type == "text" || type == "json") - return reader.readAsText(url); - else if(type == "blob") - return reader.readAsBinaryString(url); - } - return null; - } + fetchFile: function (url, type, on_complete, on_error) { + var that = this; + if (!url) return null; + + type = type || "text"; + if (url.constructor === String) { + if (url.substr(0, 4) == "http" && LiteGraph.proxy) { + url = LiteGraph.proxy + url.substr(url.indexOf(":") + 3); + } + return fetch(url) + .then(function (response) { + if (!response.ok) throw new Error("File not found"); //it will be catch below + if (type == "arraybuffer") + return response.arrayBuffer(); + else if (type == "text" || type == "string") + return response.text(); + else if (type == "json") return response.json(); + else if (type == "blob") return response.blob(); + }) + .then(function (data) { + if (on_complete) on_complete(data); + }) + .catch(function (error) { + console.error("error fetching file:", url); + if (on_error) on_error(error); + }); + } else if (url.constructor === File || url.constructor === Blob) { + var reader = new FileReader(); + reader.onload = function (e) { + var v = e.target.result; + if (type == "json") v = JSON.parse(v); + if (on_complete) on_complete(v); + }; + if (type == "arraybuffer") return reader.readAsArrayBuffer(url); + else if (type == "text" || type == "json") + return reader.readAsText(url); + else if (type == "blob") return reader.readAsBinaryString(url); + } + return null; + }, }); //timer that works everywhere @@ -806,7 +802,7 @@ } else if (typeof Date != "undefined" && Date.now) { LiteGraph.getTime = Date.now.bind(Date); } else if (typeof process != "undefined") { - LiteGraph.getTime = function() { + LiteGraph.getTime = function () { var t = process.hrtime(); return t[0] * 0.001 + t[1] * 1e-6; }; @@ -850,7 +846,7 @@ 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() { + LGraph.prototype.getSupportedTypes = function () { return this.supported_types || LGraph.supported_types; }; @@ -862,7 +858,7 @@ * @method clear */ - LGraph.prototype.clear = function() { + LGraph.prototype.clear = function () { this.stop(); this.status = LGraph.STATUS_STOPPED; @@ -898,8 +894,8 @@ //custom data this.config = {}; - this.vars = {}; - this.extra = {}; //to store custom data + this.vars = {}; + this.extra = {}; //to store custom data //timing this.globaltime = 0; @@ -915,7 +911,7 @@ this.nodes_executing = []; this.nodes_actioning = []; this.nodes_executedAction = []; - + //subgraph_data this.inputs = {}; this.outputs = {}; @@ -932,7 +928,7 @@ * @param {GraphCanvas} graph_canvas */ - LGraph.prototype.attachCanvas = function(graphcanvas) { + LGraph.prototype.attachCanvas = function (graphcanvas) { if (graphcanvas.constructor != LGraphCanvas) { throw "attachCanvas expects a LGraphCanvas instance"; } @@ -953,7 +949,7 @@ * @method detachCanvas * @param {GraphCanvas} graph_canvas */ - LGraph.prototype.detachCanvas = function(graphcanvas) { + LGraph.prototype.detachCanvas = function (graphcanvas) { if (!this.list_of_graphcanvas) { return; } @@ -972,7 +968,7 @@ * @param {number} interval amount of milliseconds between executions, if 0 then it renders to the monitor refresh rate */ - LGraph.prototype.start = function(interval) { + LGraph.prototype.start = function (interval) { if (this.status == LGraph.STATUS_RUNNING) { return; } @@ -990,29 +986,30 @@ interval = interval || 0; var that = this; - //execute once per frame - if ( interval == 0 && typeof window != "undefined" && window.requestAnimationFrame ) { + //execute once per frame + if ( + interval == 0 && + typeof window != "undefined" && + window.requestAnimationFrame + ) { function on_frame() { if (that.execution_timer_id != -1) { return; } window.requestAnimationFrame(on_frame); - if(that.onBeforeStep) - that.onBeforeStep(); + if (that.onBeforeStep) that.onBeforeStep(); that.runStep(1, !that.catch_errors); - if(that.onAfterStep) - that.onAfterStep(); + if (that.onAfterStep) that.onAfterStep(); } this.execution_timer_id = -1; on_frame(); - } else { //execute every 'interval' ms - this.execution_timer_id = setInterval(function() { + } else { + //execute every 'interval' ms + this.execution_timer_id = setInterval(function () { //execute - if(that.onBeforeStep) - that.onBeforeStep(); + if (that.onBeforeStep) that.onBeforeStep(); that.runStep(1, !that.catch_errors); - if(that.onAfterStep) - that.onAfterStep(); + if (that.onAfterStep) that.onAfterStep(); }, interval); } }; @@ -1022,7 +1019,7 @@ * @method stop execution */ - LGraph.prototype.stop = function() { + LGraph.prototype.stop = function () { if (this.status == LGraph.STATUS_STOPPED) { return; } @@ -1047,11 +1044,11 @@ * Run N steps (cycles) of the graph * @method runStep * @param {number} num number of steps to run, default is 1 - * @param {Boolean} do_not_catch_errors [optional] if you want to try/catch errors + * @param {Boolean} do_not_catch_errors [optional] if you want to try/catch errors * @param {number} limit max number of nodes to execute (used to execute from start to a node) */ - LGraph.prototype.runStep = function(num, do_not_catch_errors, limit ) { + LGraph.prototype.runStep = function (num, do_not_catch_errors, limit) { num = num || 1; var start = LiteGraph.getTime(); @@ -1059,7 +1056,7 @@ //not optimal: executes possible pending actions in node, problem is it is not optimized //it is done here as if it was done in the later loop it wont be called in the node missed the onExecute - + //from now on it will iterate only on executable nodes which is faster var nodes = this._nodes_executable ? this._nodes_executable @@ -1068,18 +1065,22 @@ return; } - limit = limit || nodes.length; + limit = limit || nodes.length; if (do_not_catch_errors) { //iterations for (var i = 0; i < num; i++) { for (var j = 0; j < limit; ++j) { var node = nodes[j]; - if(LiteGraph.use_deferred_actions && node._waiting_actions && node._waiting_actions.length) + if ( + LiteGraph.use_deferred_actions && + node._waiting_actions && + node._waiting_actions.length + ) node.executePendingActions(); if (node.mode == LiteGraph.ALWAYS && node.onExecute) { //wrap node.onExecute(); - node.doExecute(); + node.doExecute(); } } @@ -1092,13 +1093,18 @@ if (this.onAfterExecute) { this.onAfterExecute(); } - } else { //catch errors + } else { + //catch errors try { //iterations for (var i = 0; i < num; i++) { for (var j = 0; j < limit; ++j) { var node = nodes[j]; - if(LiteGraph.use_deferred_actions && node._waiting_actions && node._waiting_actions.length) + if ( + LiteGraph.use_deferred_actions && + node._waiting_actions && + node._waiting_actions.length + ) node.executePendingActions(); if (node.mode == LiteGraph.ALWAYS && node.onExecute) { node.onExecute(); @@ -1147,7 +1153,7 @@ * nodes with only inputs. * @method updateExecutionOrder */ - LGraph.prototype.updateExecutionOrder = function() { + LGraph.prototype.updateExecutionOrder = function () { this._nodes_in_order = this.computeExecutionOrder(false); this._nodes_executable = []; for (var i = 0; i < this._nodes_in_order.length; ++i) { @@ -1158,7 +1164,7 @@ }; //This is more internal, it computes the executable nodes in order and returns it - LGraph.prototype.computeExecutionOrder = function( + LGraph.prototype.computeExecutionOrder = function ( only_onExecute, set_level ) { @@ -1280,7 +1286,7 @@ } //sort now by priority - L = L.sort(function(A, B) { + L = L.sort(function (A, B) { var Ap = A.constructor.priority || A.priority || 0; var Bp = B.constructor.priority || B.priority || 0; if (Ap == Bp) { @@ -1304,7 +1310,7 @@ * @method getAncestors * @return {Array} an array with all the LGraphNodes that affect this node, in order of execution */ - LGraph.prototype.getAncestors = function(node) { + LGraph.prototype.getAncestors = function (node) { var ancestors = []; var pending = [node]; var visited = {}; @@ -1327,7 +1333,7 @@ } } - ancestors.sort(function(a, b) { + ancestors.sort(function (a, b) { return a.order - b.order; }); return ancestors; @@ -1362,14 +1368,19 @@ let y = margin + LiteGraph.NODE_TITLE_HEIGHT; for (let j = 0; j < column.length; ++j) { const node = column[j]; - node.pos[0] = (layout == LiteGraph.VERTICAL_LAYOUT) ? y : x; - node.pos[1] = (layout == LiteGraph.VERTICAL_LAYOUT) ? x : y; - const max_size_index = (layout == LiteGraph.VERTICAL_LAYOUT) ? 1 : 0; + node.pos[0] = layout == LiteGraph.VERTICAL_LAYOUT ? y : x; + node.pos[1] = layout == LiteGraph.VERTICAL_LAYOUT ? x : y; + const max_size_index = + layout == LiteGraph.VERTICAL_LAYOUT ? 1 : 0; if (node.size[max_size_index] > max_size) { max_size = node.size[max_size_index]; } - const node_size_index = (layout == LiteGraph.VERTICAL_LAYOUT) ? 0 : 1; - y += node.size[node_size_index] + margin + LiteGraph.NODE_TITLE_HEIGHT; + const node_size_index = + layout == LiteGraph.VERTICAL_LAYOUT ? 0 : 1; + y += + node.size[node_size_index] + + margin + + LiteGraph.NODE_TITLE_HEIGHT; } x += max_size + margin; } @@ -1382,7 +1393,7 @@ * @method getTime * @return {number} number of milliseconds the graph has been running */ - LGraph.prototype.getTime = function() { + LGraph.prototype.getTime = function () { return this.globaltime; }; @@ -1392,7 +1403,7 @@ * @return {number} number of milliseconds the graph has been running */ - LGraph.prototype.getFixedTime = function() { + LGraph.prototype.getFixedTime = function () { return this.fixedtime; }; @@ -1403,7 +1414,7 @@ * @return {number} number of milliseconds it took the last cycle */ - LGraph.prototype.getElapsedTime = function() { + LGraph.prototype.getElapsedTime = function () { return this.elapsed_time; }; @@ -1413,7 +1424,7 @@ * @param {String} eventname the name of the event (function to be called) * @param {Array} params parameters in array format */ - LGraph.prototype.sendEventToAllNodes = function(eventname, params, mode) { + LGraph.prototype.sendEventToAllNodes = function (eventname, params, mode) { mode = mode || LiteGraph.ALWAYS; var nodes = this._nodes_in_order ? this._nodes_in_order : this._nodes; @@ -1447,7 +1458,7 @@ } }; - LGraph.prototype.sendActionToCanvas = function(action, params) { + LGraph.prototype.sendActionToCanvas = function (action, params) { if (!this.list_of_graphcanvas) { return; } @@ -1466,7 +1477,7 @@ * @param {LGraphNode} node the instance of the node */ - LGraph.prototype.add = function(node, skip_compute_order) { + LGraph.prototype.add = function (node, skip_compute_order) { if (!node) { return; } @@ -1488,8 +1499,7 @@ ); if (LiteGraph.use_uuids) { node.id = LiteGraph.uuidv4(); - } - else { + } else { node.id = ++this.last_node_id; } } @@ -1500,10 +1510,8 @@ //give him an id if (LiteGraph.use_uuids) { - if (node.id == null || node.id == -1) - node.id = LiteGraph.uuidv4(); - } - else { + if (node.id == null || node.id == -1) node.id = LiteGraph.uuidv4(); + } else { if (node.id == null || node.id == -1) { node.id = ++this.last_node_id; } else if (this.last_node_id < node.id) { @@ -1545,7 +1553,7 @@ * @param {LGraphNode} node the instance of the node */ - LGraph.prototype.remove = function(node) { + LGraph.prototype.remove = function (node) { if (node.constructor === LiteGraph.LGraphGroup) { var index = this._groups.indexOf(node); if (index != -1) { @@ -1566,7 +1574,7 @@ return; } //cannot be removed - this.beforeChange(); //sure? - almost sure is wrong + this.beforeChange(); //sure? - almost sure is wrong //disconnect inputs if (node.inputs) { @@ -1622,11 +1630,11 @@ this.onNodeRemoved(node); } - //close panels - this.sendActionToCanvas("checkPanels"); + //close panels + this.sendActionToCanvas("checkPanels"); this.setDirtyCanvas(true, true); - this.afterChange(); //sure? - almost sure is wrong + this.afterChange(); //sure? - almost sure is wrong this.change(); this.updateExecutionOrder(); @@ -1638,7 +1646,7 @@ * @param {Number} id */ - LGraph.prototype.getNodeById = function(id) { + LGraph.prototype.getNodeById = function (id) { if (id == null) { return null; } @@ -1651,7 +1659,7 @@ * @param {Class} classObject the class itself (not an string) * @return {Array} a list with all the nodes of this type */ - LGraph.prototype.findNodesByClass = function(classObject, result) { + LGraph.prototype.findNodesByClass = function (classObject, result) { result = result || []; result.length = 0; for (var i = 0, l = this._nodes.length; i < l; ++i) { @@ -1668,7 +1676,7 @@ * @param {String} type the name of the node type * @return {Array} a list with all the nodes of this type */ - LGraph.prototype.findNodesByType = function(type, result) { + LGraph.prototype.findNodesByType = function (type, result) { var type = type.toLowerCase(); result = result || []; result.length = 0; @@ -1686,7 +1694,7 @@ * @param {String} name the name of the node to search * @return {Node} the node or null */ - LGraph.prototype.findNodeByTitle = function(title) { + LGraph.prototype.findNodeByTitle = function (title) { for (var i = 0, l = this._nodes.length; i < l; ++i) { if (this._nodes[i].title == title) { return this._nodes[i]; @@ -1701,7 +1709,7 @@ * @param {String} name the name of the node to search * @return {Array} a list with all the nodes with this name */ - LGraph.prototype.findNodesByTitle = function(title) { + LGraph.prototype.findNodesByTitle = function (title) { var result = []; for (var i = 0, l = this._nodes.length; i < l; ++i) { if (this._nodes[i].title == title) { @@ -1719,18 +1727,18 @@ * @param {Array} nodes_list a list with all the nodes to search from, by default is all the nodes in the graph * @return {LGraphNode} the node at this position or null */ - LGraph.prototype.getNodeOnPos = function(x, y, nodes_list, margin) { + LGraph.prototype.getNodeOnPos = function (x, y, nodes_list, margin) { nodes_list = nodes_list || this._nodes; - var nRet = null; + var nRet = null; for (var i = nodes_list.length - 1; i >= 0; i--) { var n = nodes_list[i]; if (n.isPointInside(x, y, margin)) { // check for lesser interest nodes (TODO check for overlapping, use the top) - /*if (typeof n == "LGraphGroup"){ + /*if (typeof n == "LGraphGroup"){ nRet = n; }else{*/ - return n; - /*}*/ + return n; + /*}*/ } } return nRet; @@ -1743,7 +1751,7 @@ * @param {number} y the y coordinate in canvas space * @return {LGraphGroup} the group or null */ - LGraph.prototype.getGroupOnPos = function(x, y) { + LGraph.prototype.getGroupOnPos = function (x, y) { for (var i = this._groups.length - 1; i >= 0; i--) { var g = this._groups[i]; if (g.isPointInside(x, y, 2, true)) { @@ -1758,7 +1766,7 @@ * this replaces the ones using the old version with the new version * @method checkNodeTypes */ - LGraph.prototype.checkNodeTypes = function() { + LGraph.prototype.checkNodeTypes = function () { var changes = false; for (var i = 0; i < this._nodes.length; i++) { var node = this._nodes[i]; @@ -1785,7 +1793,7 @@ // ********** GLOBALS ***************** - LGraph.prototype.onAction = function(action, param, options) { + LGraph.prototype.onAction = function (action, param, options) { this._input_nodes = this.findNodesByClass( LiteGraph.GraphInput, this._input_nodes @@ -1801,7 +1809,7 @@ } }; - LGraph.prototype.trigger = function(action, param) { + LGraph.prototype.trigger = function (action, param) { if (this.onTrigger) { this.onTrigger(action, param); } @@ -1814,17 +1822,17 @@ * @param {String} type * @param {*} value [optional] */ - LGraph.prototype.addInput = function(name, type, value) { + LGraph.prototype.addInput = function (name, type, value) { var input = this.inputs[name]; if (input) { //already exist return; } - this.beforeChange(); + this.beforeChange(); this.inputs[name] = { name: name, type: type, value: value }; this._version++; - this.afterChange(); + this.afterChange(); if (this.onInputAdded) { this.onInputAdded(name, type); @@ -1841,7 +1849,7 @@ * @param {String} name * @param {*} data */ - LGraph.prototype.setInputData = function(name, data) { + LGraph.prototype.setInputData = function (name, data) { var input = this.inputs[name]; if (!input) { return; @@ -1855,7 +1863,7 @@ * @param {String} name * @return {*} the data */ - LGraph.prototype.getInputData = function(name) { + LGraph.prototype.getInputData = function (name) { var input = this.inputs[name]; if (!input) { return null; @@ -1869,7 +1877,7 @@ * @param {String} old_name * @param {String} new_name */ - LGraph.prototype.renameInput = function(old_name, name) { + LGraph.prototype.renameInput = function (old_name, name) { if (name == old_name) { return; } @@ -1902,7 +1910,7 @@ * @param {String} name * @param {String} type */ - LGraph.prototype.changeInputType = function(name, type) { + LGraph.prototype.changeInputType = function (name, type) { if (!this.inputs[name]) { return false; } @@ -1928,7 +1936,7 @@ * @param {String} name * @param {String} type */ - LGraph.prototype.removeInput = function(name) { + LGraph.prototype.removeInput = function (name) { if (!this.inputs[name]) { return false; } @@ -1953,7 +1961,7 @@ * @param {String} type * @param {*} value */ - LGraph.prototype.addOutput = function(name, type, value) { + LGraph.prototype.addOutput = function (name, type, value) { this.outputs[name] = { name: name, type: type, value: value }; this._version++; @@ -1972,7 +1980,7 @@ * @param {String} name * @param {String} value */ - LGraph.prototype.setOutputData = function(name, value) { + LGraph.prototype.setOutputData = function (name, value) { var output = this.outputs[name]; if (!output) { return; @@ -1986,7 +1994,7 @@ * @param {String} name * @return {*} the data */ - LGraph.prototype.getOutputData = function(name) { + LGraph.prototype.getOutputData = function (name) { var output = this.outputs[name]; if (!output) { return null; @@ -2000,7 +2008,7 @@ * @param {String} old_name * @param {String} new_name */ - LGraph.prototype.renameOutput = function(old_name, name) { + LGraph.prototype.renameOutput = function (old_name, name) { if (!this.outputs[old_name]) { return false; } @@ -2029,7 +2037,7 @@ * @param {String} name * @param {String} type */ - LGraph.prototype.changeOutputType = function(name, type) { + LGraph.prototype.changeOutputType = function (name, type) { if (!this.outputs[name]) { return false; } @@ -2054,7 +2062,7 @@ * @method removeOutput * @param {String} name */ - LGraph.prototype.removeOutput = function(name) { + LGraph.prototype.removeOutput = function (name) { if (!this.outputs[name]) { return false; } @@ -2071,37 +2079,37 @@ return true; }; - LGraph.prototype.triggerInput = function(name, value) { + LGraph.prototype.triggerInput = function (name, value) { var nodes = this.findNodesByTitle(name); for (var i = 0; i < nodes.length; ++i) { nodes[i].onTrigger(value); } }; - LGraph.prototype.setCallback = function(name, func) { + LGraph.prototype.setCallback = function (name, func) { var nodes = this.findNodesByTitle(name); for (var i = 0; i < nodes.length; ++i) { nodes[i].setTrigger(func); } }; - //used for undo, called before any change is made to the graph - LGraph.prototype.beforeChange = function(info) { + //used for undo, called before any change is made to the graph + LGraph.prototype.beforeChange = function (info) { if (this.onBeforeChange) { - this.onBeforeChange(this,info); + this.onBeforeChange(this, info); } this.sendActionToCanvas("onBeforeChange", this); }; - //used to resend actions, called after any change is made to the graph - LGraph.prototype.afterChange = function(info) { + //used to resend actions, called after any change is made to the graph + LGraph.prototype.afterChange = function (info) { if (this.onAfterChange) { - this.onAfterChange(this,info); + this.onAfterChange(this, info); } this.sendActionToCanvas("onAfterChange", this); }; - LGraph.prototype.connectionChange = function(node, link_info) { + LGraph.prototype.connectionChange = function (node, link_info) { this.updateExecutionOrder(); if (this.onConnectionChange) { this.onConnectionChange(node); @@ -2115,7 +2123,7 @@ * @method isLive */ - LGraph.prototype.isLive = function() { + LGraph.prototype.isLive = function () { if (!this.list_of_graphcanvas) { return false; } @@ -2133,7 +2141,7 @@ * clears the triggered slot animation in all links (stop visual animation) * @method clearTriggeredSlots */ - LGraph.prototype.clearTriggeredSlots = function() { + LGraph.prototype.clearTriggeredSlots = function () { for (var i in this.links) { var link_info = this.links[i]; if (!link_info) { @@ -2146,7 +2154,7 @@ }; /* Called when something visually changed (not the graph!) */ - LGraph.prototype.change = function() { + LGraph.prototype.change = function () { if (LiteGraph.debug) { console.log("Graph changed"); } @@ -2156,7 +2164,7 @@ } }; - LGraph.prototype.setDirtyCanvas = function(fg, bg) { + LGraph.prototype.setDirtyCanvas = function (fg, bg) { this.sendActionToCanvas("setDirty", [fg, bg]); }; @@ -2165,7 +2173,7 @@ * @method removeLink * @param {Number} link_id */ - LGraph.prototype.removeLink = function(link_id) { + LGraph.prototype.removeLink = function (link_id) { var link = this.links[link_id]; if (!link) { return; @@ -2182,7 +2190,7 @@ * @method serialize * @return {Object} value of the node */ - LGraph.prototype.serialize = function() { + LGraph.prototype.serialize = function () { var nodes_info = []; for (var i = 0, l = this._nodes.length; i < l; ++i) { nodes_info.push(this._nodes[i].serialize()); @@ -2199,7 +2207,7 @@ "weird LLink bug, link info is not a LLink but a regular object" ); var link2 = new LLink(); - for (var j in link) { + for (var j in link) { link2[j] = link[j]; } this.links[i] = link2; @@ -2221,12 +2229,11 @@ links: links, groups: groups_info, config: this.config, - extra: this.extra, - version: LiteGraph.VERSION + extra: this.extra, + version: LiteGraph.VERSION, }; - if(this.onSerialize) - this.onSerialize(data); + if (this.onSerialize) this.onSerialize(data); return data; }; @@ -2237,7 +2244,7 @@ * @param {String} str configure a graph from a JSON string * @param {Boolean} returns if there was any error parsing */ - LGraph.prototype.configure = function(data, keep_old) { + LGraph.prototype.configure = function (data, keep_old) { if (!data) { return; } @@ -2253,11 +2260,13 @@ var links = []; for (var i = 0; i < data.links.length; ++i) { var link_data = data.links[i]; - if(!link_data) //weird bug - { - console.warn("serialized graph link data contains errors, skipping."); - continue; - } + if (!link_data) { + //weird bug + console.warn( + "serialized graph link data contains errors, skipping." + ); + continue; + } var link = new LLink(); link.configure(link_data); links[link.id] = link; @@ -2267,8 +2276,9 @@ //copy all stored fields for (var i in data) { - if(i == "nodes" || i == "groups" ) //links must be accepted - continue; + if (i == "nodes" || i == "groups") + //links must be accepted + continue; this[i] = data[i]; } @@ -2321,54 +2331,50 @@ this.updateExecutionOrder(); - this.extra = data.extra || {}; + this.extra = data.extra || {}; - if(this.onConfigure) - this.onConfigure(data); + if (this.onConfigure) this.onConfigure(data); this._version++; this.setDirtyCanvas(true, true); return error; }; - LGraph.prototype.load = function(url, callback) { + LGraph.prototype.load = function (url, callback) { var that = this; - //from file - if(url.constructor === File || url.constructor === Blob) - { - var reader = new FileReader(); - reader.addEventListener('load', function(event) { - var data = JSON.parse(event.target.result); - that.configure(data); - if(callback) - callback(); - }); - - reader.readAsText(url); - return; - } - - //is a string, then an URL + //from file + if (url.constructor === File || url.constructor === Blob) { + var reader = new FileReader(); + reader.addEventListener("load", function (event) { + var data = JSON.parse(event.target.result); + that.configure(data); + if (callback) callback(); + }); + + reader.readAsText(url); + return; + } + + //is a string, then an URL var req = new XMLHttpRequest(); req.open("GET", url, true); req.send(null); - req.onload = function(oEvent) { + req.onload = function (oEvent) { if (req.status !== 200) { console.error("Error loading graph:", req.status, req.response); return; } - var data = JSON.parse( req.response ); + var data = JSON.parse(req.response); that.configure(data); - if(callback) - callback(); + if (callback) callback(); }; - req.onerror = function(err) { + req.onerror = function (err) { console.error("Error loading graph:", err); }; }; - LGraph.prototype.onNodeTrace = function(node, msg, color) { + LGraph.prototype.onNodeTrace = function (node, msg, color) { //TODO }; @@ -2385,7 +2391,7 @@ this._pos = new Float32Array(2); //center } - LLink.prototype.configure = function(o) { + LLink.prototype.configure = function (o) { if (o.constructor === Array) { this.id = o[0]; this.origin_id = o[1]; @@ -2403,14 +2409,14 @@ } }; - LLink.prototype.serialize = function() { + LLink.prototype.serialize = function () { return [ this.id, this.origin_id, this.origin_slot, this.target_id, this.target_slot, - this.type + this.type, ]; }; @@ -2483,7 +2489,7 @@ global.LGraphNode = LiteGraph.LGraphNode = LGraphNode; - LGraphNode.prototype._ctor = function(title) { + LGraphNode.prototype._ctor = function (title) { this.title = title || "Unnamed"; this.size = [LiteGraph.NODE_WIDTH, 60]; this.graph = null; @@ -2491,23 +2497,22 @@ this._pos = new Float32Array(10, 10); Object.defineProperty(this, "pos", { - set: function(v) { + set: function (v) { if (!v || v.length < 2) { return; } this._pos[0] = v[0]; this._pos[1] = v[1]; }, - get: function() { + get: function () { return this._pos; }, - enumerable: true + enumerable: true, }); if (LiteGraph.use_uuids) { this.id = LiteGraph.uuidv4(); - } - else { + } else { this.id = -1; //not know till not added } this.type = null; @@ -2528,7 +2533,7 @@ * configure a node from an object containing the serialized info * @method configure */ - LGraphNode.prototype.configure = function(info) { + LGraphNode.prototype.configure = function (info) { if (this.graph) { this.graph._version++; } @@ -2538,7 +2543,7 @@ for (var k in info.properties) { this.properties[k] = info.properties[k]; if (this.onPropertyChanged) { - this.onPropertyChanged( k, info.properties[k] ); + this.onPropertyChanged(k, info.properties[k]); } } continue; @@ -2563,54 +2568,70 @@ this.title = this.constructor.title; } - if (this.inputs) { - for (var i = 0; i < this.inputs.length; ++i) { - var input = this.inputs[i]; - var link_info = this.graph ? this.graph.links[input.link] : null; - if (this.onConnectionsChange) - this.onConnectionsChange( LiteGraph.INPUT, i, true, link_info, input ); //link_info has been created now, so its updated + if (this.inputs) { + for (var i = 0; i < this.inputs.length; ++i) { + var input = this.inputs[i]; + var link_info = this.graph + ? this.graph.links[input.link] + : null; + if (this.onConnectionsChange) + this.onConnectionsChange( + LiteGraph.INPUT, + i, + true, + link_info, + input + ); //link_info has been created now, so its updated + + if (this.onInputAdded) this.onInputAdded(input); + } + } - if( this.onInputAdded ) - this.onInputAdded(input); + if (this.outputs) { + for (var i = 0; i < this.outputs.length; ++i) { + var output = this.outputs[i]; + if (!output.links) { + continue; + } + for (var j = 0; j < output.links.length; ++j) { + var link_info = this.graph + ? this.graph.links[output.links[j]] + : null; + if (this.onConnectionsChange) + this.onConnectionsChange( + LiteGraph.OUTPUT, + i, + true, + link_info, + output + ); //link_info has been created now, so its updated + } - } - } - - if (this.outputs) { - for (var i = 0; i < this.outputs.length; ++i) { - var output = this.outputs[i]; - if (!output.links) { - continue; - } - for (var j = 0; j < output.links.length; ++j) { - var link_info = this.graph ? this.graph.links[output.links[j]] : null; - if (this.onConnectionsChange) - this.onConnectionsChange( LiteGraph.OUTPUT, i, true, link_info, output ); //link_info has been created now, so its updated - } - - if( this.onOutputAdded ) - this.onOutputAdded(output); - } + if (this.onOutputAdded) this.onOutputAdded(output); + } } - if( this.widgets ) - { - for (var i = 0; i < this.widgets.length; ++i) - { - var w = this.widgets[i]; - if(!w) - continue; - if(w.options && w.options.property && (this.properties[ w.options.property ] != undefined)) - w.value = JSON.parse( JSON.stringify( this.properties[ w.options.property ] ) ); - } - if (info.widgets_values) { - for (var i = 0; i < info.widgets_values.length; ++i) { - if (this.widgets[i]) { - this.widgets[i].value = info.widgets_values[i]; - } - } - } - } + if (this.widgets) { + for (var i = 0; i < this.widgets.length; ++i) { + var w = this.widgets[i]; + if (!w) continue; + if ( + w.options && + w.options.property && + this.properties[w.options.property] != undefined + ) + w.value = JSON.parse( + JSON.stringify(this.properties[w.options.property]) + ); + } + if (info.widgets_values) { + for (var i = 0; i < info.widgets_values.length; ++i) { + if (this.widgets[i]) { + this.widgets[i].value = info.widgets_values[i]; + } + } + } + } if (this.onConfigure) { this.onConfigure(info); @@ -2622,7 +2643,7 @@ * @method serialize */ - LGraphNode.prototype.serialize = function() { + LGraphNode.prototype.serialize = function () { //create serialization object var o = { id: this.id, @@ -2630,8 +2651,8 @@ pos: this.pos, size: this.size, flags: LiteGraph.cloneObject(this.flags), - order: this.order, - mode: this.mode + order: this.order, + mode: this.mode, }; //special case for when there were errors @@ -2662,10 +2683,9 @@ if (this.widgets && this.serialize_widgets) { o.widgets_values = []; for (var i = 0; i < this.widgets.length; ++i) { - if(this.widgets[i]) - o.widgets_values[i] = this.widgets[i].value; - else - o.widgets_values[i] = null; + if (this.widgets[i]) + o.widgets_values[i] = this.widgets[i].value; + else o.widgets_values[i] = null; } } @@ -2698,7 +2718,7 @@ }; /* Creates a clone of this node */ - LGraphNode.prototype.clone = function() { + LGraphNode.prototype.clone = function () { var node = LiteGraph.createNode(this.type); if (!node) { return null; @@ -2725,7 +2745,7 @@ delete data["id"]; if (LiteGraph.use_uuids) { - data["id"] = LiteGraph.uuidv4() + data["id"] = LiteGraph.uuidv4(); } //remove links @@ -2739,7 +2759,7 @@ * @method toString */ - LGraphNode.prototype.toString = function() { + LGraphNode.prototype.toString = function () { return JSON.stringify(this.serialize()); }; //LGraphNode.prototype.deserialize = function(info) {} //this cannot be done from within, must be done in LiteGraph @@ -2749,7 +2769,7 @@ * @method getTitle */ - LGraphNode.prototype.getTitle = function() { + LGraphNode.prototype.getTitle = function () { return this.title || this.constructor.title; }; @@ -2759,30 +2779,28 @@ * @param {String} name * @param {*} value */ - LGraphNode.prototype.setProperty = function(name, value) { + LGraphNode.prototype.setProperty = function (name, value) { if (!this.properties) { this.properties = {}; } - if( value === this.properties[name] ) - return; - var prev_value = this.properties[name]; + if (value === this.properties[name]) return; + var prev_value = this.properties[name]; this.properties[name] = value; if (this.onPropertyChanged) { - if( this.onPropertyChanged(name, value, prev_value) === false ) //abort change - this.properties[name] = prev_value; + if (this.onPropertyChanged(name, value, prev_value) === false) + //abort change + this.properties[name] = prev_value; } - if(this.widgets) //widgets could be linked to properties - for(var i = 0; i < this.widgets.length; ++i) - { - var w = this.widgets[i]; - if(!w) - continue; - if(w.options.property == name) - { - w.value = value; - break; - } - } + if (this.widgets) + //widgets could be linked to properties + for (var i = 0; i < this.widgets.length; ++i) { + var w = this.widgets[i]; + if (!w) continue; + if (w.options.property == name) { + w.value = value; + break; + } + } }; // Execution ************************* @@ -2792,7 +2810,7 @@ * @param {number} slot * @param {*} data */ - LGraphNode.prototype.setOutputData = function(slot, data) { + LGraphNode.prototype.setOutputData = function (slot, data) { if (!this.outputs) { return; } @@ -2817,9 +2835,8 @@ if (this.outputs[slot].links) { for (var i = 0; i < this.outputs[slot].links.length; i++) { var link_id = this.outputs[slot].links[i]; - var link = this.graph.links[link_id]; - if(link) - link.data = data; + var link = this.graph.links[link_id]; + if (link) link.data = data; } } }; @@ -2830,7 +2847,7 @@ * @param {number} slot * @param {String} datatype */ - LGraphNode.prototype.setOutputDataType = function(slot, type) { + LGraphNode.prototype.setOutputDataType = function (slot, type) { if (!this.outputs) { return; } @@ -2860,7 +2877,7 @@ * @param {boolean} force_update if set to true it will force the connected node of this slot to output data into this link * @return {*} data or if it is not connected returns undefined */ - LGraphNode.prototype.getInputData = function(slot, force_update) { + LGraphNode.prototype.getInputData = function (slot, force_update) { if (!this.inputs) { return; } //undefined; @@ -2901,7 +2918,7 @@ * @param {number} slot * @return {String} datatype in string format */ - LGraphNode.prototype.getInputDataType = function(slot) { + LGraphNode.prototype.getInputDataType = function (slot) { if (!this.inputs) { return null; } //undefined; @@ -2933,7 +2950,7 @@ * @param {boolean} force_update if set to true it will force the connected node of this slot to output data into this link * @return {*} data or if it is not connected returns null */ - LGraphNode.prototype.getInputDataByName = function( + LGraphNode.prototype.getInputDataByName = function ( slot_name, force_update ) { @@ -2950,7 +2967,7 @@ * @param {number} slot * @return {boolean} */ - LGraphNode.prototype.isInputConnected = function(slot) { + LGraphNode.prototype.isInputConnected = function (slot) { if (!this.inputs) { return false; } @@ -2963,7 +2980,7 @@ * @param {number} slot * @return {Object} object or null { link: id, name: string, type: string or 0 } */ - LGraphNode.prototype.getInputInfo = function(slot) { + LGraphNode.prototype.getInputInfo = function (slot) { if (!this.inputs) { return null; } @@ -2979,13 +2996,13 @@ * @param {number} slot * @return {LLink} object or null */ - LGraphNode.prototype.getInputLink = function(slot) { + LGraphNode.prototype.getInputLink = function (slot) { if (!this.inputs) { return null; } if (slot < this.inputs.length) { var slot_info = this.inputs[slot]; - return this.graph.links[ slot_info.link ]; + return this.graph.links[slot_info.link]; } return null; }; @@ -2996,7 +3013,7 @@ * @param {number} slot * @return {LGraphNode} node or null */ - LGraphNode.prototype.getInputNode = function(slot) { + LGraphNode.prototype.getInputNode = function (slot) { if (!this.inputs) { return null; } @@ -3020,7 +3037,7 @@ * @param {string} name * @return {*} value */ - LGraphNode.prototype.getInputOrProperty = function(name) { + LGraphNode.prototype.getInputOrProperty = function (name) { if (!this.inputs || !this.inputs.length) { return this.properties ? this.properties[name] : null; } @@ -3043,7 +3060,7 @@ * @param {number} slot * @return {Object} object or null */ - LGraphNode.prototype.getOutputData = function(slot) { + LGraphNode.prototype.getOutputData = function (slot) { if (!this.outputs) { return null; } @@ -3061,7 +3078,7 @@ * @param {number} slot * @return {Object} object or null { name: string, type: string, links: [ ids of links in number ] } */ - LGraphNode.prototype.getOutputInfo = function(slot) { + LGraphNode.prototype.getOutputInfo = function (slot) { if (!this.outputs) { return null; } @@ -3077,7 +3094,7 @@ * @param {number} slot * @return {boolean} */ - LGraphNode.prototype.isOutputConnected = function(slot) { + LGraphNode.prototype.isOutputConnected = function (slot) { if (!this.outputs) { return false; } @@ -3093,7 +3110,7 @@ * @method isAnyOutputConnected * @return {boolean} */ - LGraphNode.prototype.isAnyOutputConnected = function() { + LGraphNode.prototype.isAnyOutputConnected = function () { if (!this.outputs) { return false; } @@ -3111,7 +3128,7 @@ * @param {number} slot * @return {array} */ - LGraphNode.prototype.getOutputNodes = function(slot) { + LGraphNode.prototype.getOutputNodes = function (slot) { if (!this.outputs || this.outputs.length == 0) { return null; } @@ -3139,56 +3156,62 @@ return r; }; - LGraphNode.prototype.addOnTriggerInput = function(){ + LGraphNode.prototype.addOnTriggerInput = function () { var trigS = this.findInputSlot("onTrigger"); - if (trigS == -1){ //!trigS || - var input = this.addInput("onTrigger", LiteGraph.EVENT, {optional: true, nameLocked: true}); + if (trigS == -1) { + //!trigS || + var input = this.addInput("onTrigger", LiteGraph.EVENT, { + optional: true, + nameLocked: true, + }); return this.findInputSlot("onTrigger"); } return trigS; - } - - LGraphNode.prototype.addOnExecutedOutput = function(){ + }; + + LGraphNode.prototype.addOnExecutedOutput = function () { var trigS = this.findOutputSlot("onExecuted"); - if (trigS == -1){ //!trigS || - var output = this.addOutput("onExecuted", LiteGraph.ACTION, {optional: true, nameLocked: true}); + if (trigS == -1) { + //!trigS || + var output = this.addOutput("onExecuted", LiteGraph.ACTION, { + optional: true, + nameLocked: true, + }); return this.findOutputSlot("onExecuted"); } return trigS; - } - - LGraphNode.prototype.onAfterExecuteNode = function(param, options){ + }; + + LGraphNode.prototype.onAfterExecuteNode = function (param, options) { var trigS = this.findOutputSlot("onExecuted"); - if (trigS != -1){ - + if (trigS != -1) { //console.debug(this.id+":"+this.order+" triggering slot onAfterExecute"); //console.debug(param); //console.debug(options); this.triggerSlot(trigS, param, null, options); - } - } - - LGraphNode.prototype.changeMode = function(modeTo){ - switch(modeTo){ + }; + + LGraphNode.prototype.changeMode = function (modeTo) { + switch (modeTo) { case LiteGraph.ON_EVENT: // this.addOnExecutedOutput(); break; - + case LiteGraph.ON_TRIGGER: this.addOnTriggerInput(); this.addOnExecutedOutput(); break; - + case LiteGraph.NEVER: break; - + case LiteGraph.ALWAYS: break; - + case LiteGraph.ON_REQUEST: break; - + default: return false; break; @@ -3200,97 +3223,107 @@ /** * Triggers the execution of actions that were deferred when the action was triggered * @method executePendingActions - */ - LGraphNode.prototype.executePendingActions = function() { - if(!this._waiting_actions || !this._waiting_actions.length) - return; - for(var i = 0; i < this._waiting_actions.length;++i) - { + */ + LGraphNode.prototype.executePendingActions = function () { + if (!this._waiting_actions || !this._waiting_actions.length) return; + for (var i = 0; i < this._waiting_actions.length; ++i) { var p = this._waiting_actions[i]; - this.onAction(p[0],p[1],p[2],p[3],p[4]); - } + this.onAction(p[0], p[1], p[2], p[3], p[4]); + } this._waiting_actions.length = 0; - } + }; - /** * Triggers the node code execution, place a boolean/counter to mark the node as being executed * @method doExecute * @param {*} param * @param {*} options */ - LGraphNode.prototype.doExecute = function(param, options) { + LGraphNode.prototype.doExecute = function (param, options) { options = options || {}; - if (this.onExecute){ - + if (this.onExecute) { // enable this to give the event an ID - if (!options.action_call) options.action_call = this.id+"_exec_"+Math.floor(Math.random()*9999); - + if (!options.action_call) + options.action_call = + this.id + "_exec_" + Math.floor(Math.random() * 9999); + this.graph.nodes_executing[this.id] = true; //.push(this.id); this.onExecute(param, options); - + this.graph.nodes_executing[this.id] = false; //.pop(); - + // save execution/action ref this.exec_version = this.graph.iteration; - if(options && options.action_call){ + if (options && options.action_call) { this.action_call = options.action_call; // if (param) this.graph.nodes_executedAction[this.id] = options.action_call; } - } - else { + } else { } this.execute_triggered = 2; // the nFrames it will be used (-- each step), means "how old" is the event - if(this.onAfterExecuteNode) this.onAfterExecuteNode(param, options); // callback + if (this.onAfterExecuteNode) this.onAfterExecuteNode(param, options); // callback }; - + /** * Triggers an action, wrapped by logics to control execution flow * @method actionDo * @param {String} action name * @param {*} param */ - LGraphNode.prototype.actionDo = function(action, param, options, action_slot ) { + LGraphNode.prototype.actionDo = function ( + action, + param, + options, + action_slot + ) { options = options || {}; - if (this.onAction){ - - // enable this to give the event an ID - if (!options.action_call) options.action_call = this.id+"_"+(action?action:"action")+"_"+Math.floor(Math.random()*9999); - - this.graph.nodes_actioning[this.id] = (action?action:"actioning"); //.push(this.id); - + if (this.onAction) { + // enable this to give the event an ID + if (!options.action_call) + options.action_call = + this.id + + "_" + + (action ? action : "action") + + "_" + + Math.floor(Math.random() * 9999); + + this.graph.nodes_actioning[this.id] = action ? action : "actioning"; //.push(this.id); + this.onAction(action, param, options, action_slot); - + this.graph.nodes_actioning[this.id] = false; //.pop(); - + // save execution/action ref - if(options && options.action_call){ + if (options && options.action_call) { this.action_call = options.action_call; // if (param) this.graph.nodes_executedAction[this.id] = options.action_call; } } this.action_triggered = 2; // the nFrames it will be used (-- each step), means "how old" is the event - if(this.onAfterExecuteNode) this.onAfterExecuteNode(param, options); + if (this.onAfterExecuteNode) this.onAfterExecuteNode(param, options); }; - + /** * Triggers an event in this node, this will trigger any output with the same name * @method trigger * @param {String} event name ( "on_play", ... ) if action is equivalent to false then the event is send to all * @param {*} param */ - LGraphNode.prototype.trigger = function(action, param, options) { + LGraphNode.prototype.trigger = function (action, param, options) { if (!this.outputs || !this.outputs.length) { return; } - if (this.graph) - this.graph._last_trigger_time = LiteGraph.getTime(); + if (this.graph) this.graph._last_trigger_time = LiteGraph.getTime(); for (var i = 0; i < this.outputs.length; ++i) { var output = this.outputs[i]; - if ( !output || output.type !== LiteGraph.EVENT || (action && output.name != action) ) + if ( + !output || + output.type !== LiteGraph.EVENT || + (action && output.name != action) + ) continue; this.triggerSlot(i, param, null, options); } @@ -3303,20 +3336,26 @@ * @param {*} param * @param {Number} link_id [optional] in case you want to trigger and specific output link in a slot */ - LGraphNode.prototype.triggerSlot = function(slot, param, link_id, options) { + LGraphNode.prototype.triggerSlot = function ( + slot, + param, + link_id, + options + ) { options = options || {}; if (!this.outputs) { return; } - if(slot == null) - { - console.error("slot must be a number"); - return; - } + if (slot == null) { + console.error("slot must be a number"); + return; + } - if(slot.constructor !== Number) - console.warn("slot must be a number, use node.trigger('name') if you want to use a string"); + if (slot.constructor !== Number) + console.warn( + "slot must be a number, use node.trigger('name') if you want to use a string" + ); var output = this.outputs[slot]; if (!output) { @@ -3354,32 +3393,40 @@ //used to mark events in graph var target_connection = node.inputs[link_info.target_slot]; - if (node.mode === LiteGraph.ON_TRIGGER) - { - // generate unique trigger ID if not present - if (!options.action_call) options.action_call = this.id+"_trigg_"+Math.floor(Math.random()*9999); + if (node.mode === LiteGraph.ON_TRIGGER) { + // generate unique trigger ID if not present + if (!options.action_call) + options.action_call = + this.id + "_trigg_" + Math.floor(Math.random() * 9999); if (node.onExecute) { // -- wrapping node.onExecute(param); -- node.doExecute(param, options); } - } - else if (node.onAction) { + } else if (node.onAction) { // generate unique action ID if not present - if (!options.action_call) options.action_call = this.id+"_act_"+Math.floor(Math.random()*9999); + if (!options.action_call) + options.action_call = + this.id + "_act_" + Math.floor(Math.random() * 9999); //pass the action name var target_connection = node.inputs[link_info.target_slot]; //instead of executing them now, it will be executed in the next graph loop, to ensure data flow - if(LiteGraph.use_deferred_actions && node.onExecute) - { - if(!node._waiting_actions) - node._waiting_actions = []; - node._waiting_actions.push([target_connection.name, param, options, link_info.target_slot]); - } - else - { + if (LiteGraph.use_deferred_actions && node.onExecute) { + if (!node._waiting_actions) node._waiting_actions = []; + node._waiting_actions.push([ + target_connection.name, + param, + options, + link_info.target_slot, + ]); + } else { // wrap node.onAction(target_connection.name, param); - node.actionDo( target_connection.name, param, options, link_info.target_slot ); + node.actionDo( + target_connection.name, + param, + options, + link_info.target_slot + ); } } } @@ -3391,7 +3438,7 @@ * @param {Number} slot the index of the output slot * @param {Number} link_id [optional] in case you want to trigger and specific output link in a slot */ - LGraphNode.prototype.clearTriggeredSlot = function(slot, link_id) { + LGraphNode.prototype.clearTriggeredSlot = function (slot, link_id) { if (!this.outputs) { return; } @@ -3427,12 +3474,10 @@ * @method setSize * @param {vec2} size */ - LGraphNode.prototype.setSize = function(size) - { - this.size = size; - if(this.onResize) - this.onResize(this.size); - } + LGraphNode.prototype.setSize = function (size) { + this.size = size; + if (this.onResize) this.onResize(this.size); + }; /** * add a new property to this node @@ -3442,7 +3487,7 @@ * @param {string} type string defining the output type ("vec3","number",...) * @param {Object} extra_info this can be used to have special properties of the property (like values, etc) */ - LGraphNode.prototype.addProperty = function( + LGraphNode.prototype.addProperty = function ( name, default_value, type, @@ -3474,7 +3519,7 @@ * @param {string} type string defining the output type ("vec3","number",...) * @param {Object} extra_info this can be used to have special properties of an output (label, special color, position, etc) */ - LGraphNode.prototype.addOutput = function(name, type, extra_info) { + LGraphNode.prototype.addOutput = function (name, type, extra_info) { var output = { name: name, type: type, links: null }; if (extra_info) { for (var i in extra_info) { @@ -3489,10 +3534,11 @@ if (this.onOutputAdded) { this.onOutputAdded(output); } - - if (LiteGraph.auto_load_slot_types) LiteGraph.registerNodeAndSlotType(this,type,true); - - this.setSize( this.computeSize() ); + + if (LiteGraph.auto_load_slot_types) + LiteGraph.registerNodeAndSlotType(this, type, true); + + this.setSize(this.computeSize()); this.setDirtyCanvas(true, true); return output; }; @@ -3502,7 +3548,7 @@ * @method addOutputs * @param {Array} array of triplets like [[name,type,extra_info],[...]] */ - LGraphNode.prototype.addOutputs = function(array) { + LGraphNode.prototype.addOutputs = function (array) { for (var i = 0; i < array.length; ++i) { var info = array[i]; var o = { name: info[0], type: info[1], link: null }; @@ -3519,12 +3565,12 @@ if (this.onOutputAdded) { this.onOutputAdded(o); } - - if (LiteGraph.auto_load_slot_types) LiteGraph.registerNodeAndSlotType(this,info[1],true); - + + if (LiteGraph.auto_load_slot_types) + LiteGraph.registerNodeAndSlotType(this, info[1], true); } - this.setSize( this.computeSize() ); + this.setSize(this.computeSize()); this.setDirtyCanvas(true, true); }; @@ -3533,7 +3579,7 @@ * @method removeOutput * @param {number} slot */ - LGraphNode.prototype.removeOutput = function(slot) { + LGraphNode.prototype.removeOutput = function (slot) { this.disconnectOutput(slot); this.outputs.splice(slot, 1); for (var i = slot; i < this.outputs.length; ++i) { @@ -3550,7 +3596,7 @@ } } - this.setSize( this.computeSize() ); + this.setSize(this.computeSize()); if (this.onOutputRemoved) { this.onOutputRemoved(slot); } @@ -3564,7 +3610,7 @@ * @param {string} type string defining the input type ("vec3","number",...), it its a generic one use 0 * @param {Object} extra_info this can be used to have special properties of an input (label, color, position, etc) */ - LGraphNode.prototype.addInput = function(name, type, extra_info) { + LGraphNode.prototype.addInput = function (name, type, extra_info) { type = type || 0; var input = { name: name, type: type, link: null }; if (extra_info) { @@ -3578,13 +3624,13 @@ } this.inputs.push(input); - this.setSize( this.computeSize() ); + this.setSize(this.computeSize()); if (this.onInputAdded) { this.onInputAdded(input); - } - - LiteGraph.registerNodeAndSlotType(this,type); + } + + LiteGraph.registerNodeAndSlotType(this, type); this.setDirtyCanvas(true, true); return input; @@ -3595,7 +3641,7 @@ * @method addInputs * @param {Array} array of triplets like [[name,type,extra_info],[...]] */ - LGraphNode.prototype.addInputs = function(array) { + LGraphNode.prototype.addInputs = function (array) { for (var i = 0; i < array.length; ++i) { var info = array[i]; var o = { name: info[0], type: info[1], link: null }; @@ -3612,11 +3658,11 @@ if (this.onInputAdded) { this.onInputAdded(o); } - - LiteGraph.registerNodeAndSlotType(this,info[1]); + + LiteGraph.registerNodeAndSlotType(this, info[1]); } - this.setSize( this.computeSize() ); + this.setSize(this.computeSize()); this.setDirtyCanvas(true, true); }; @@ -3625,7 +3671,7 @@ * @method removeInput * @param {number} slot */ - LGraphNode.prototype.removeInput = function(slot) { + LGraphNode.prototype.removeInput = function (slot) { this.disconnectInput(slot); var slot_info = this.inputs.splice(slot, 1); for (var i = slot; i < this.inputs.length; ++i) { @@ -3638,9 +3684,9 @@ } link.target_slot -= 1; } - this.setSize( this.computeSize() ); + this.setSize(this.computeSize()); if (this.onInputRemoved) { - this.onInputRemoved(slot, slot_info[0] ); + this.onInputRemoved(slot, slot_info[0]); } this.setDirtyCanvas(true, true); }; @@ -3653,13 +3699,13 @@ * @param {[x,y]} pos position of the connection inside the node * @param {string} direction if is input or output */ - LGraphNode.prototype.addConnection = function(name, type, pos, direction) { + LGraphNode.prototype.addConnection = function (name, type, pos, direction) { var o = { name: name, type: type, pos: pos, direction: direction, - links: null + links: null, }; this.connections.push(o); return o; @@ -3671,7 +3717,7 @@ * @param {vec2} minHeight * @return {vec2} the total size */ - LGraphNode.prototype.computeSize = function(out) { + LGraphNode.prototype.computeSize = function (out) { if (this.constructor.size) { return this.constructor.size.concat(); } @@ -3716,26 +3762,26 @@ size[0] = Math.max(size[0], LiteGraph.NODE_WIDTH * 1.5); } - size[1] = (this.constructor.slot_start_y || 0) + rows * LiteGraph.NODE_SLOT_HEIGHT; + size[1] = + (this.constructor.slot_start_y || 0) + + rows * LiteGraph.NODE_SLOT_HEIGHT; var widgets_height = 0; if (this.widgets && this.widgets.length) { for (var i = 0, l = this.widgets.length; i < l; ++i) { if (this.widgets[i].computeSize) - widgets_height += this.widgets[i].computeSize(size[0])[1] + 4; - else - widgets_height += LiteGraph.NODE_WIDGET_HEIGHT + 4; + widgets_height += + this.widgets[i].computeSize(size[0])[1] + 4; + else widgets_height += LiteGraph.NODE_WIDGET_HEIGHT + 4; } widgets_height += 8; } //compute height using widgets height - if( this.widgets_up ) - size[1] = Math.max( size[1], widgets_height ); - else if( this.widgets_start_y != null ) - size[1] = Math.max( size[1], widgets_height + this.widgets_start_y ); - else - size[1] += widgets_height; + if (this.widgets_up) size[1] = Math.max(size[1], widgets_height); + else if (this.widgets_start_y != null) + size[1] = Math.max(size[1], widgets_height + this.widgets_start_y); + else size[1] += widgets_height; function compute_text_size(text) { if (!text) { @@ -3762,14 +3808,13 @@ * @method getPropertyInfo * @param {String} property name of the property * @return {Object} the object with all the available info - */ - LGraphNode.prototype.getPropertyInfo = function( property ) - { + */ + LGraphNode.prototype.getPropertyInfo = function (property) { var info = null; - //there are several ways to define info about a property - //legacy mode - if (this.properties_info) { + //there are several ways to define info about a property + //legacy mode + if (this.properties_info) { for (var i = 0; i < this.properties_info.length; ++i) { if (this.properties_info[i].name == property) { info = this.properties_info[i]; @@ -3777,27 +3822,27 @@ } } } - //litescene mode using the constructor - if(this.constructor["@" + property]) - info = this.constructor["@" + property]; + //litescene mode using the constructor + if (this.constructor["@" + property]) + info = this.constructor["@" + property]; - if(this.constructor.widgets_info && this.constructor.widgets_info[property]) - info = this.constructor.widgets_info[property]; + if ( + this.constructor.widgets_info && + this.constructor.widgets_info[property] + ) + info = this.constructor.widgets_info[property]; - //litescene mode using the constructor - if (!info && this.onGetPropertyInfo) { + //litescene mode using the constructor + if (!info && this.onGetPropertyInfo) { info = this.onGetPropertyInfo(property); } - if (!info) - info = {}; - if(!info.type) - info.type = typeof this.properties[property]; - if(info.widget == "combo") - info.type = "enum"; + if (!info) info = {}; + if (!info.type) info.type = typeof this.properties[property]; + if (info.widget == "combo") info.type = "enum"; - return info; - } + return info; + }; /** * Defines a widget inside the node, it will be rendered on top of the node, you can control lots of properties @@ -3807,44 +3852,47 @@ * @param {String} name the text to show on the widget * @param {String} value the default value * @param {Function|String} callback function to call when it changes (optionally, it can be the name of the property to modify) - * @param {Object} options the object that contains special properties of this widget + * @param {Object} options the object that contains special properties of this widget * @return {Object} the created widget object */ - LGraphNode.prototype.addWidget = function( type, name, value, callback, options ) - { + LGraphNode.prototype.addWidget = function ( + type, + name, + value, + callback, + options + ) { if (!this.widgets) { this.widgets = []; } - if(!options && callback && callback.constructor === Object) - { - options = callback; - callback = null; - } + if (!options && callback && callback.constructor === Object) { + options = callback; + callback = null; + } - if(options && options.constructor === String) //options can be the property name - options = { property: options }; + if (options && options.constructor === String) + //options can be the property name + options = { property: options }; - if(callback && callback.constructor === String) //callback can be the property name - { - if(!options) - options = {}; - options.property = callback; - callback = null; - } + if (callback && callback.constructor === String) { + //callback can be the property name + if (!options) options = {}; + options.property = callback; + callback = null; + } - if(callback && callback.constructor !== Function) - { - console.warn("addWidget: callback must be a function"); - callback = null; - } + if (callback && callback.constructor !== Function) { + console.warn("addWidget: callback must be a function"); + callback = null; + } var w = { type: type.toLowerCase(), name: name, value: value, callback: callback, - options: options || {} + options: options || {}, }; if (w.options.y !== undefined) { @@ -3852,17 +3900,19 @@ } if (!callback && !w.options.callback && !w.options.property) { - console.warn("LiteGraph addWidget(...) without a callback or property assigned"); + console.warn( + "LiteGraph addWidget(...) without a callback or property assigned" + ); } if (type == "combo" && !w.options.values) { throw "LiteGraph addWidget('combo',...) requires to pass values in options: { values:['red','blue'] }"; } this.widgets.push(w); - this.setSize( this.computeSize() ); + this.setSize(this.computeSize()); return w; }; - LGraphNode.prototype.addCustomWidget = function(custom_widget) { + LGraphNode.prototype.addCustomWidget = function (custom_widget) { if (!this.widgets) { this.widgets = []; } @@ -3877,18 +3927,18 @@ * @param compute_outer {boolean?} [optional] set to true to include the shadow and connection points in the bounding calculation * @return {Float32Array[4]} the bounding box in format of [topleft_cornerx, topleft_cornery, width, height] */ - LGraphNode.prototype.getBounding = function(out, compute_outer) { + LGraphNode.prototype.getBounding = function (out, compute_outer) { out = out || new Float32Array(4); const nodePos = this.pos; const isCollapsed = this.flags.collapsed; const nodeSize = this.size; - + let left_offset = 0; // 1 offset due to how nodes are rendered - let right_offset = 1 ; + let right_offset = 1; let top_offset = 0; let bottom_offset = 0; - + if (compute_outer) { // 4 offset for collapsed node connection points left_offset = 4; @@ -3899,15 +3949,16 @@ // 5 offset for bottom shadow and collapsed node connection points bottom_offset = 5 + top_offset; } - + out[0] = nodePos[0] - left_offset; out[1] = nodePos[1] - LiteGraph.NODE_TITLE_HEIGHT - top_offset; - out[2] = isCollapsed ? - (this._collapsed_width || LiteGraph.NODE_COLLAPSED_WIDTH) + right_offset : - nodeSize[0] + right_offset; - out[3] = isCollapsed ? - LiteGraph.NODE_TITLE_HEIGHT + bottom_offset : - nodeSize[1] + LiteGraph.NODE_TITLE_HEIGHT + bottom_offset; + out[2] = isCollapsed + ? (this._collapsed_width || LiteGraph.NODE_COLLAPSED_WIDTH) + + right_offset + : nodeSize[0] + right_offset; + out[3] = isCollapsed + ? LiteGraph.NODE_TITLE_HEIGHT + bottom_offset + : nodeSize[1] + LiteGraph.NODE_TITLE_HEIGHT + bottom_offset; if (this.onBounding) { this.onBounding(out); @@ -3922,10 +3973,11 @@ * @param {number} y * @return {boolean} */ - LGraphNode.prototype.isPointInside = function(x, y, margin, skip_title) { + LGraphNode.prototype.isPointInside = function (x, y, margin, skip_title) { margin = margin || 0; - var margin_top = this.graph && this.graph.isLive() ? 0 : LiteGraph.NODE_TITLE_HEIGHT; + var margin_top = + this.graph && this.graph.isLive() ? 0 : LiteGraph.NODE_TITLE_HEIGHT; if (skip_title) { margin_top = 0; } @@ -3962,7 +4014,7 @@ * @param {number} y * @return {Object} if found the object contains { input|output: slot object, slot: number, link_pos: [x,y] } */ - LGraphNode.prototype.getSlotInPosition = function(x, y) { + LGraphNode.prototype.getSlotInPosition = function (x, y) { //search for inputs var link_pos = new Float32Array(2); if (this.inputs) { @@ -4013,7 +4065,7 @@ * @param {boolean} returnObj if the obj itself wanted * @return {number_or_object} the slot (-1 if not found) */ - LGraphNode.prototype.findInputSlot = function(name, returnObj) { + LGraphNode.prototype.findInputSlot = function (name, returnObj) { if (!this.inputs) { return -1; } @@ -4032,7 +4084,7 @@ * @param {boolean} returnObj if the obj itself wanted * @return {number_or_object} the slot (-1 if not found) */ - LGraphNode.prototype.findOutputSlot = function(name, returnObj) { + LGraphNode.prototype.findOutputSlot = function (name, returnObj) { returnObj = returnObj || false; if (!this.outputs) { return -1; @@ -4044,21 +4096,19 @@ } return -1; }; - + // TODO refactor: USE SINGLE findInput/findOutput functions! :: merge options - + /** * returns the first free input slot * @method findInputSlotFree * @param {object} options * @return {number_or_object} the slot (-1 if not found) */ - LGraphNode.prototype.findInputSlotFree = function(optsIn) { + LGraphNode.prototype.findInputSlotFree = function (optsIn) { var optsIn = optsIn || {}; - var optsDef = {returnObj: false - ,typesNotAccepted: [] - }; - var opts = Object.assign(optsDef,optsIn); + var optsDef = { returnObj: false, typesNotAccepted: [] }; + var opts = Object.assign(optsDef, optsIn); if (!this.inputs) { return -1; } @@ -4066,7 +4116,11 @@ if (this.inputs[i].link && this.inputs[i].link != null) { continue; } - if (opts.typesNotAccepted && opts.typesNotAccepted.includes && opts.typesNotAccepted.includes(this.inputs[i].type)){ + if ( + opts.typesNotAccepted && + opts.typesNotAccepted.includes && + opts.typesNotAccepted.includes(this.inputs[i].type) + ) { continue; } return !opts.returnObj ? i : this.inputs[i]; @@ -4080,12 +4134,10 @@ * @param {object} options * @return {number_or_object} the slot (-1 if not found) */ - LGraphNode.prototype.findOutputSlotFree = function(optsIn) { + LGraphNode.prototype.findOutputSlotFree = function (optsIn) { var optsIn = optsIn || {}; - var optsDef = { returnObj: false - ,typesNotAccepted: [] - }; - var opts = Object.assign(optsDef,optsIn); + var optsDef = { returnObj: false, typesNotAccepted: [] }; + var opts = Object.assign(optsDef, optsIn); if (!this.outputs) { return -1; } @@ -4093,28 +4145,54 @@ if (this.outputs[i].links && this.outputs[i].links != null) { continue; } - if (opts.typesNotAccepted && opts.typesNotAccepted.includes && opts.typesNotAccepted.includes(this.outputs[i].type)){ + if ( + opts.typesNotAccepted && + opts.typesNotAccepted.includes && + opts.typesNotAccepted.includes(this.outputs[i].type) + ) { continue; } return !opts.returnObj ? i : this.outputs[i]; } return -1; }; - + /** * findSlotByType for INPUTS */ - LGraphNode.prototype.findInputSlotByType = function(type, returnObj, preferFreeSlot, doNotUseOccupied) { - return this.findSlotByType(true, type, returnObj, preferFreeSlot, doNotUseOccupied); + LGraphNode.prototype.findInputSlotByType = function ( + type, + returnObj, + preferFreeSlot, + doNotUseOccupied + ) { + return this.findSlotByType( + true, + type, + returnObj, + preferFreeSlot, + doNotUseOccupied + ); }; /** * findSlotByType for OUTPUTS */ - LGraphNode.prototype.findOutputSlotByType = function(type, returnObj, preferFreeSlot, doNotUseOccupied) { - return this.findSlotByType(false, type, returnObj, preferFreeSlot, doNotUseOccupied); + LGraphNode.prototype.findOutputSlotByType = function ( + type, + returnObj, + preferFreeSlot, + doNotUseOccupied + ) { + return this.findSlotByType( + false, + type, + returnObj, + preferFreeSlot, + doNotUseOccupied + ); }; - + /** * returns the output (or input) slot with a given type, -1 if not found * @method findSlotByType @@ -4124,7 +4202,13 @@ * @param {boolean} preferFreeSlot if we want a free slot (if not found, will return the first of the type anyway) * @return {number_or_object} the slot (-1 if not found) */ - LGraphNode.prototype.findSlotByType = function(input, type, returnObj, preferFreeSlot, doNotUseOccupied) { + LGraphNode.prototype.findSlotByType = function ( + input, + type, + returnObj, + preferFreeSlot, + doNotUseOccupied + ) { input = input || false; returnObj = returnObj || false; preferFreeSlot = preferFreeSlot || false; @@ -4133,37 +4217,48 @@ if (!aSlots) { return -1; } - // !! empty string type is considered 0, * !! - if (type == "" || type == "*") type = 0; + // !! empty string type is considered 0, * !! + if (type == "" || type == "*") type = 0; for (var i = 0, l = aSlots.length; i < l; ++i) { var tFound = false; - var aSource = (type+"").toLowerCase().split(","); - var aDest = aSlots[i].type=="0"||aSlots[i].type=="*"?"0":aSlots[i].type; - aDest = (aDest+"").toLowerCase().split(","); - for(var sI=0;sI= 0 && target_slot !== null){ + var target_slot = target_node.findInputSlotByType( + target_slotType, + false, + true + ); + if (target_slot >= 0 && target_slot !== null) { //console.debug("CONNbyTYPE type "+target_slotType+" for "+target_slot) return this.connect(slot, target_node, target_slot); - }else{ + } else { //console.log("type "+target_slotType+" not found or not free?") - if (opts.createEventInCase && target_slotType == LiteGraph.EVENT){ + if (opts.createEventInCase && target_slotType == LiteGraph.EVENT) { // WILL CREATE THE onTrigger IN SLOT - //console.debug("connect WILL CREATE THE onTrigger "+target_slotType+" to "+target_node); + //console.debug("connect WILL CREATE THE onTrigger "+target_slotType+" to "+target_node); return this.connect(slot, target_node, -1); } - // connect to the first general output slot if not found a specific type and - if (opts.generalTypeInCase){ - var target_slot = target_node.findInputSlotByType(0, false, true, true); - //console.debug("connect TO a general type (*, 0), if not found the specific type ",target_slotType," to ",target_node,"RES_SLOT:",target_slot); - if (target_slot >= 0){ + // connect to the first general output slot if not found a specific type and + if (opts.generalTypeInCase) { + var target_slot = target_node.findInputSlotByType( + 0, + false, + true, + true + ); + //console.debug("connect TO a general type (*, 0), if not found the specific type ",target_slotType," to ",target_node,"RES_SLOT:",target_slot); + if (target_slot >= 0) { return this.connect(slot, target_node, target_slot); } } // connect to the first free input slot if not found a specific type and this output is general - if (opts.firstFreeIfOutputGeneralInCase && (target_slotType == 0 || target_slotType == "*" || target_slotType == "")){ - var target_slot = target_node.findInputSlotFree({typesNotAccepted: [LiteGraph.EVENT] }); - //console.debug("connect TO TheFirstFREE ",target_slotType," to ",target_node,"RES_SLOT:",target_slot); - if (target_slot >= 0){ - return this.connect(slot, target_node, target_slot); + if ( + opts.firstFreeIfOutputGeneralInCase && + (target_slotType == 0 || + target_slotType == "*" || + target_slotType == "") + ) { + var target_slot = target_node.findInputSlotFree({ + typesNotAccepted: [LiteGraph.EVENT], + }); + //console.debug("connect TO TheFirstFREE ",target_slotType," to ",target_node,"RES_SLOT:",target_slot); + if (target_slot >= 0) { + return this.connect(slot, target_node, target_slot); } } - - console.debug("no way to connect type: ",target_slotType," to targetNODE ",target_node); - //TODO filter - - return null; - } - } - + + console.debug( + "no way to connect type: ", + target_slotType, + " to targetNODE ", + target_node + ); + //TODO filter + + return null; + } + }; + /** * connect this node input to the output of another node BY TYPE * @method connectByType @@ -4235,53 +4357,79 @@ * @param {string} target_type the output slot type of the target node * @return {Object} the link_info is created, otherwise null */ - LGraphNode.prototype.connectByTypeOutput = function(slot, source_node, source_slotType, optsIn) { + LGraphNode.prototype.connectByTypeOutput = function ( + slot, + source_node, + source_slotType, + optsIn + ) { var optsIn = optsIn || {}; - var optsDef = { createEventInCase: true - ,firstFreeIfInputGeneralInCase: true - ,generalTypeInCase: true - }; - var opts = Object.assign(optsDef,optsIn); + var optsDef = { + createEventInCase: true, + firstFreeIfInputGeneralInCase: true, + generalTypeInCase: true, + }; + var opts = Object.assign(optsDef, optsIn); if (source_node && source_node.constructor === Number) { source_node = this.graph.getNodeById(source_node); } - var source_slot = source_node.findOutputSlotByType(source_slotType, false, true); - if (source_slot >= 0 && source_slot !== null){ + var source_slot = source_node.findOutputSlotByType( + source_slotType, + false, + true + ); + if (source_slot >= 0 && source_slot !== null) { //console.debug("CONNbyTYPE OUT! type "+source_slotType+" for "+source_slot) return source_node.connect(source_slot, this, slot); - }else{ - - // connect to the first general output slot if not found a specific type and - if (opts.generalTypeInCase){ - var source_slot = source_node.findOutputSlotByType(0, false, true, true); - if (source_slot >= 0){ + } else { + // connect to the first general output slot if not found a specific type and + if (opts.generalTypeInCase) { + var source_slot = source_node.findOutputSlotByType( + 0, + false, + true, + true + ); + if (source_slot >= 0) { return source_node.connect(source_slot, this, slot); } } - - if (opts.createEventInCase && source_slotType == LiteGraph.EVENT){ + + if (opts.createEventInCase && source_slotType == LiteGraph.EVENT) { // WILL CREATE THE onExecuted OUT SLOT - if (LiteGraph.do_add_triggers_slots){ - var source_slot = source_node.addOnExecutedOutput(); - return source_node.connect(source_slot, this, slot); - } + if (LiteGraph.do_add_triggers_slots) { + var source_slot = source_node.addOnExecutedOutput(); + return source_node.connect(source_slot, this, slot); + } } // connect to the first free output slot if not found a specific type and this input is general - if (opts.firstFreeIfInputGeneralInCase && (source_slotType == 0 || source_slotType == "*" || source_slotType == "")){ - var source_slot = source_node.findOutputSlotFree({typesNotAccepted: [LiteGraph.EVENT] }); - if (source_slot >= 0){ + if ( + opts.firstFreeIfInputGeneralInCase && + (source_slotType == 0 || + source_slotType == "*" || + source_slotType == "") + ) { + var source_slot = source_node.findOutputSlotFree({ + typesNotAccepted: [LiteGraph.EVENT], + }); + if (source_slot >= 0) { return source_node.connect(source_slot, this, slot); } } - - console.debug("no way to connect byOUT type: ",source_slotType," to sourceNODE ",source_node); - //TODO filter - + + console.debug( + "no way to connect byOUT type: ", + source_slotType, + " to sourceNODE ", + source_node + ); + //TODO filter + //console.log("type OUT! "+source_slotType+" not found or not free?") return null; } - } - + }; + /** * connect this node output to the input of another node * @method connect @@ -4290,7 +4438,7 @@ * @param {number_or_string} target_slot the input slot of the target node (could be the number of the slot or the string with the name of the slot, or -1 to connect a trigger) * @return {Object} the link_info is created, otherwise null */ - LGraphNode.prototype.connect = function(slot, target_node, target_slot) { + LGraphNode.prototype.connect = function (slot, target_node, target_slot) { target_slot = target_slot || 0; if (!this.graph) { @@ -4341,16 +4489,15 @@ return null; } } else if (target_slot === LiteGraph.EVENT) { - - if (LiteGraph.do_add_triggers_slots){ - //search for first slot with event? :: NO this is done outside - //console.log("Connect: Creating triggerEvent"); - // force mode - target_node.changeMode(LiteGraph.ON_TRIGGER); - target_slot = target_node.findInputSlot("onTrigger"); - }else{ - return null; // -- break -- - } + if (LiteGraph.do_add_triggers_slots) { + //search for first slot with event? :: NO this is done outside + //console.log("Connect: Creating triggerEvent"); + // force mode + target_node.changeMode(LiteGraph.ON_TRIGGER); + target_slot = target_node.findInputSlot("onTrigger"); + } else { + return null; // -- break -- + } } else if ( !target_node.inputs || target_slot >= target_node.inputs.length @@ -4361,13 +4508,13 @@ return null; } - var changed = false; + var changed = false; var input = target_node.inputs[target_slot]; var link_info = null; var output = this.outputs[slot]; - - if (!this.outputs[slot]){ + + if (!this.outputs[slot]) { /*console.debug("Invalid slot passed: "+slot); console.debug(this.outputs);*/ return null; @@ -4379,116 +4526,140 @@ target_slot = target_node.onBeforeConnectInput(target_slot); //callback } - //check target_slot and check connection types - if (target_slot===false || target_slot===null || !LiteGraph.isValidConnection(output.type, input.type)) - { - this.setDirtyCanvas(false, true); - if(changed) - this.graph.connectionChange(this, link_info); - return null; - }else{ - //console.debug("valid connection",output.type, input.type); - } + //check target_slot and check connection types + if ( + target_slot === false || + target_slot === null || + !LiteGraph.isValidConnection(output.type, input.type) + ) { + this.setDirtyCanvas(false, true); + if (changed) this.graph.connectionChange(this, link_info); + return null; + } else { + //console.debug("valid connection",output.type, input.type); + } //allows nodes to block connection, callback if (target_node.onConnectInput) { - if ( target_node.onConnectInput(target_slot, output.type, output, this, slot) === false ) { + if ( + target_node.onConnectInput( + target_slot, + output.type, + output, + this, + slot + ) === false + ) { return null; } } - if (this.onConnectOutput) { // callback - if ( this.onConnectOutput(slot, input.type, input, target_node, target_slot) === false ) { + if (this.onConnectOutput) { + // callback + if ( + this.onConnectOutput( + slot, + input.type, + input, + target_node, + target_slot + ) === false + ) { return null; } } //if there is something already plugged there, disconnect - if (target_node.inputs[target_slot] && target_node.inputs[target_slot].link != null) { - this.graph.beforeChange(); - target_node.disconnectInput(target_slot, {doProcessChange: false}); - changed = true; + if ( + target_node.inputs[target_slot] && + target_node.inputs[target_slot].link != null + ) { + this.graph.beforeChange(); + target_node.disconnectInput(target_slot, { + doProcessChange: false, + }); + changed = true; } - if (output.links !== null && output.links.length){ - switch(output.type){ + if (output.links !== null && output.links.length) { + switch (output.type) { case LiteGraph.EVENT: - if (!LiteGraph.allow_multi_output_for_events){ + if (!LiteGraph.allow_multi_output_for_events) { this.graph.beforeChange(); - this.disconnectOutput(slot, false, {doProcessChange: false}); // Input(target_slot, {doProcessChange: false}); + this.disconnectOutput(slot, false, { + doProcessChange: false, + }); // Input(target_slot, {doProcessChange: false}); changed = true; } - break; + break; default: - break; + break; } } - var nextId - if (LiteGraph.use_uuids) - nextId = LiteGraph.uuidv4(); - else - nextId = ++this.graph.last_link_id; - - //create link class - link_info = new LLink( - nextId, - input.type || output.type, - this.id, - slot, - target_node.id, - target_slot - ); - - //add to graph links list - this.graph.links[link_info.id] = link_info; - - //connect in output - if (output.links == null) { - output.links = []; - } - output.links.push(link_info.id); - //connect in input - target_node.inputs[target_slot].link = link_info.id; - if (this.graph) { - this.graph._version++; - } - if (this.onConnectionsChange) { - this.onConnectionsChange( - LiteGraph.OUTPUT, - slot, - true, - link_info, - output - ); - } //link_info has been created now, so its updated - if (target_node.onConnectionsChange) { - target_node.onConnectionsChange( - LiteGraph.INPUT, - target_slot, - true, - link_info, - input - ); - } - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.INPUT, - target_node, - target_slot, - this, - slot - ); - this.graph.onNodeConnectionChange( - LiteGraph.OUTPUT, - this, - slot, - target_node, - target_slot - ); - } + var nextId; + if (LiteGraph.use_uuids) nextId = LiteGraph.uuidv4(); + else nextId = ++this.graph.last_link_id; + + //create link class + link_info = new LLink( + nextId, + input.type || output.type, + this.id, + slot, + target_node.id, + target_slot + ); + + //add to graph links list + this.graph.links[link_info.id] = link_info; + + //connect in output + if (output.links == null) { + output.links = []; + } + output.links.push(link_info.id); + //connect in input + target_node.inputs[target_slot].link = link_info.id; + if (this.graph) { + this.graph._version++; + } + if (this.onConnectionsChange) { + this.onConnectionsChange( + LiteGraph.OUTPUT, + slot, + true, + link_info, + output + ); + } //link_info has been created now, so its updated + if (target_node.onConnectionsChange) { + target_node.onConnectionsChange( + LiteGraph.INPUT, + target_slot, + true, + link_info, + input + ); + } + if (this.graph && this.graph.onNodeConnectionChange) { + this.graph.onNodeConnectionChange( + LiteGraph.INPUT, + target_node, + target_slot, + this, + slot + ); + this.graph.onNodeConnectionChange( + LiteGraph.OUTPUT, + this, + slot, + target_node, + target_slot + ); + } this.setDirtyCanvas(false, true); - this.graph.afterChange(); - this.graph.connectionChange(this, link_info); + this.graph.afterChange(); + this.graph.connectionChange(this, link_info); return link_info; }; @@ -4500,7 +4671,7 @@ * @param {LGraphNode} target_node the target node to which this slot is connected [Optional, if not target_node is specified all nodes will be disconnected] * @return {boolean} if it was disconnected successfully */ - LGraphNode.prototype.disconnectOutput = function(slot, target_node) { + LGraphNode.prototype.disconnectOutput = function (slot, target_node) { if (slot.constructor === String) { slot = this.findOutputSlot(slot); if (slot == -1) { @@ -4656,7 +4827,7 @@ * @param {number_or_string} slot (could be the number of the slot or the string with the name of the slot) * @return {boolean} if it was disconnected successfully */ - LGraphNode.prototype.disconnectInput = function(slot) { + LGraphNode.prototype.disconnectInput = function (slot) { //seek for the output slot if (slot.constructor === String) { slot = this.findInputSlot(slot); @@ -4679,67 +4850,69 @@ } var link_id = this.inputs[slot].link; - if(link_id != null) - { - this.inputs[slot].link = null; - - //remove other side - var link_info = this.graph.links[link_id]; - if (link_info) { - var target_node = this.graph.getNodeById(link_info.origin_id); - if (!target_node) { - return false; - } - - var output = target_node.outputs[link_info.origin_slot]; - if (!output || !output.links || output.links.length == 0) { - return false; - } - - //search in the inputs list for this link - for (var i = 0, l = output.links.length; i < l; i++) { - if (output.links[i] == link_id) { - output.links.splice(i, 1); - break; - } - } - - delete this.graph.links[link_id]; //remove from the pool - if (this.graph) { - this.graph._version++; - } - if (this.onConnectionsChange) { - this.onConnectionsChange( - LiteGraph.INPUT, - slot, - false, - link_info, - input - ); - } - if (target_node.onConnectionsChange) { - target_node.onConnectionsChange( - LiteGraph.OUTPUT, - i, - false, - link_info, - output - ); - } - if (this.graph && this.graph.onNodeConnectionChange) { - this.graph.onNodeConnectionChange( - LiteGraph.OUTPUT, - target_node, - i - ); - this.graph.onNodeConnectionChange(LiteGraph.INPUT, this, slot); - } - } - } //link != null + if (link_id != null) { + this.inputs[slot].link = null; + + //remove other side + var link_info = this.graph.links[link_id]; + if (link_info) { + var target_node = this.graph.getNodeById(link_info.origin_id); + if (!target_node) { + return false; + } + + var output = target_node.outputs[link_info.origin_slot]; + if (!output || !output.links || output.links.length == 0) { + return false; + } + + //search in the inputs list for this link + for (var i = 0, l = output.links.length; i < l; i++) { + if (output.links[i] == link_id) { + output.links.splice(i, 1); + break; + } + } + + delete this.graph.links[link_id]; //remove from the pool + if (this.graph) { + this.graph._version++; + } + if (this.onConnectionsChange) { + this.onConnectionsChange( + LiteGraph.INPUT, + slot, + false, + link_info, + input + ); + } + if (target_node.onConnectionsChange) { + target_node.onConnectionsChange( + LiteGraph.OUTPUT, + i, + false, + link_info, + output + ); + } + if (this.graph && this.graph.onNodeConnectionChange) { + this.graph.onNodeConnectionChange( + LiteGraph.OUTPUT, + target_node, + i + ); + this.graph.onNodeConnectionChange( + LiteGraph.INPUT, + this, + slot + ); + } + } + } //link != null this.setDirtyCanvas(false, true); - if(this.graph) - this.graph.connectionChange(this); + if (this.graph) this.graph.connectionChange(this); return true; }; @@ -4751,7 +4924,7 @@ * @param {vec2} out [optional] a place to store the output, to free garbage * @return {[x,y]} the position **/ - LGraphNode.prototype.getConnectionPos = function( + LGraphNode.prototype.getConnectionPos = function ( is_input, slot_number, out @@ -4839,7 +5012,7 @@ }; /* Force align to grid */ - LGraphNode.prototype.alignToGrid = function() { + LGraphNode.prototype.alignToGrid = function () { this.pos[0] = LiteGraph.CANVAS_GRID_SIZE * Math.round(this.pos[0] / LiteGraph.CANVAS_GRID_SIZE); @@ -4849,7 +5022,7 @@ }; /* Console output */ - LGraphNode.prototype.trace = function(msg) { + LGraphNode.prototype.trace = function (msg) { if (!this.console) { this.console = []; } @@ -4859,12 +5032,11 @@ this.console.shift(); } - if(this.graph.onNodeTrace) - this.graph.onNodeTrace(this, msg); + if (this.graph.onNodeTrace) this.graph.onNodeTrace(this, msg); }; /* Forces to redraw or the main canvas (LGraphNode) or the bg canvas (links) */ - LGraphNode.prototype.setDirtyCanvas = function( + LGraphNode.prototype.setDirtyCanvas = function ( dirty_foreground, dirty_background ) { @@ -4873,17 +5045,17 @@ } this.graph.sendActionToCanvas("setDirty", [ dirty_foreground, - dirty_background + dirty_background, ]); }; - LGraphNode.prototype.loadImage = function(url) { + LGraphNode.prototype.loadImage = function (url) { var img = new Image(); img.src = LiteGraph.node_images_path + url; img.ready = false; var that = this; - img.onload = function() { + img.onload = function () { this.ready = true; that.setDirtyCanvas(true); }; @@ -4930,7 +5102,7 @@ LGraphNode.prototype.executeAction = function(action) */ /* Allows to get onMouseMove and onMouseUp events even if the mouse is out of focus */ - LGraphNode.prototype.captureInput = function(v) { + LGraphNode.prototype.captureInput = function (v) { if (!this.graph || !this.graph.list_of_graphcanvas) { return; } @@ -4953,7 +5125,7 @@ LGraphNode.prototype.executeAction = function(action) * Collapse the node to make it smaller on the canvas * @method collapse **/ - LGraphNode.prototype.collapse = function(force) { + LGraphNode.prototype.collapse = function (force) { this.graph._version++; if (this.constructor.collapsable === false && !force) { return; @@ -4971,7 +5143,7 @@ LGraphNode.prototype.executeAction = function(action) * @method pin **/ - LGraphNode.prototype.pin = function(v) { + LGraphNode.prototype.pin = function (v) { this.graph._version++; if (v === undefined) { this.flags.pinned = !this.flags.pinned; @@ -4980,10 +5152,10 @@ LGraphNode.prototype.executeAction = function(action) } }; - LGraphNode.prototype.localToScreen = function(x, y, graphcanvas) { + LGraphNode.prototype.localToScreen = function (x, y, graphcanvas) { return [ (x + this.pos[0]) * graphcanvas.scale + graphcanvas.offset[0], - (y + this.pos[1]) * graphcanvas.scale + graphcanvas.offset[1] + (y + this.pos[1]) * graphcanvas.scale + graphcanvas.offset[1], ]; }; @@ -4993,7 +5165,7 @@ LGraphNode.prototype.executeAction = function(action) global.LGraphGroup = LiteGraph.LGraphGroup = LGraphGroup; - LGraphGroup.prototype._ctor = function(title) { + LGraphGroup.prototype._ctor = function (title) { this.title = title || "Group"; this.font_size = 24; this.color = LGraphCanvas.node_colors.pale_blue @@ -5006,42 +5178,42 @@ LGraphNode.prototype.executeAction = function(action) this.graph = null; Object.defineProperty(this, "pos", { - set: function(v) { + set: function (v) { if (!v || v.length < 2) { return; } this._pos[0] = v[0]; this._pos[1] = v[1]; }, - get: function() { + get: function () { return this._pos; }, - enumerable: true + enumerable: true, }); Object.defineProperty(this, "size", { - set: function(v) { + set: function (v) { if (!v || v.length < 2) { return; } this._size[0] = Math.max(140, v[0]); this._size[1] = Math.max(80, v[1]); }, - get: function() { + get: function () { return this._size; }, - enumerable: true + enumerable: true, }); }; - LGraphGroup.prototype.configure = function(o) { + LGraphGroup.prototype.configure = function (o) { this.title = o.title; this._bounding.set(o.bounding); this.color = o.color; this.font_size = o.font_size; }; - LGraphGroup.prototype.serialize = function() { + LGraphGroup.prototype.serialize = function () { var b = this._bounding; return { title: this.title, @@ -5049,14 +5221,14 @@ LGraphNode.prototype.executeAction = function(action) Math.round(b[0]), Math.round(b[1]), Math.round(b[2]), - Math.round(b[3]) + Math.round(b[3]), ], color: this.color, - font_size: this.font_size + font_size: this.font_size, }; }; - LGraphGroup.prototype.move = function(deltax, deltay, ignore_nodes) { + LGraphGroup.prototype.move = function (deltax, deltay, ignore_nodes) { this._pos[0] += deltax; this._pos[1] += deltay; if (ignore_nodes) { @@ -5069,7 +5241,7 @@ LGraphNode.prototype.executeAction = function(action) } }; - LGraphGroup.prototype.recomputeInsideNodes = function() { + LGraphGroup.prototype.recomputeInsideNodes = function () { this._nodes.length = 0; var nodes = this.graph._nodes; var node_bounding = new Float32Array(4); @@ -5111,14 +5283,26 @@ LGraphNode.prototype.executeAction = function(action) LiteGraph.DragAndScale = DragAndScale; - DragAndScale.prototype.bindEvents = function(element) { + DragAndScale.prototype.bindEvents = function (element) { this.last_mouse = new Float32Array(2); this._binded_mouse_callback = this.onMouse.bind(this); - LiteGraph.pointerListenerAdd(element,"down", this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(element,"move", this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(element,"up", this._binded_mouse_callback); + LiteGraph.pointerListenerAdd( + element, + "down", + this._binded_mouse_callback + ); + LiteGraph.pointerListenerAdd( + element, + "move", + this._binded_mouse_callback + ); + LiteGraph.pointerListenerAdd( + element, + "up", + this._binded_mouse_callback + ); element.addEventListener( "mousewheel", @@ -5128,22 +5312,25 @@ LGraphNode.prototype.executeAction = function(action) element.addEventListener("wheel", this._binded_mouse_callback, false); }; - DragAndScale.prototype.computeVisibleArea = function( viewport ) { + DragAndScale.prototype.computeVisibleArea = function (viewport) { if (!this.element) { - this.visible_area[0] = this.visible_area[1] = this.visible_area[2] = this.visible_area[3] = 0; + this.visible_area[0] = + this.visible_area[1] = + this.visible_area[2] = + this.visible_area[3] = + 0; return; } var width = this.element.width; var height = this.element.height; var startx = -this.offset[0]; var starty = -this.offset[1]; - if( viewport ) - { - startx += viewport[0] / this.scale; - starty += viewport[1] / this.scale; - width = viewport[2]; - height = viewport[3]; - } + if (viewport) { + startx += viewport[0] / this.scale; + starty += viewport[1] / this.scale; + width = viewport[2]; + height = viewport[3]; + } var endx = startx + width / this.scale; var endy = starty + height / this.scale; this.visible_area[0] = startx; @@ -5152,7 +5339,7 @@ LGraphNode.prototype.executeAction = function(action) this.visible_area[3] = endy - starty; }; - DragAndScale.prototype.onMouse = function(e) { + DragAndScale.prototype.onMouse = function (e) { if (!this.enabled) { return; } @@ -5164,22 +5351,40 @@ LGraphNode.prototype.executeAction = function(action) e.canvasx = x; e.canvasy = y; e.dragging = this.dragging; - - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); - //console.log("pointerevents: DragAndScale onMouse "+e.type+" "+is_inside); - + var is_inside = + !this.viewport || + (this.viewport && + x >= this.viewport[0] && + x < this.viewport[0] + this.viewport[2] && + y >= this.viewport[1] && + y < this.viewport[1] + this.viewport[3]); + + //console.log("pointerevents: DragAndScale onMouse "+e.type+" "+is_inside); + var ignore = false; if (this.onmouse) { ignore = this.onmouse(e); } - if (e.type == LiteGraph.pointerevents_method+"down" && is_inside) { + if (e.type == LiteGraph.pointerevents_method + "down" && is_inside) { this.dragging = true; - LiteGraph.pointerListenerRemove(canvas,"move",this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(document,"move",this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(document,"up",this._binded_mouse_callback); - } else if (e.type == LiteGraph.pointerevents_method+"move") { + LiteGraph.pointerListenerRemove( + canvas, + "move", + this._binded_mouse_callback + ); + LiteGraph.pointerListenerAdd( + document, + "move", + this._binded_mouse_callback + ); + LiteGraph.pointerListenerAdd( + document, + "up", + this._binded_mouse_callback + ); + } else if (e.type == LiteGraph.pointerevents_method + "move") { if (!ignore) { var deltax = x - this.last_mouse[0]; var deltay = y - this.last_mouse[1]; @@ -5187,15 +5392,28 @@ LGraphNode.prototype.executeAction = function(action) this.mouseDrag(deltax, deltay); } } - } else if (e.type == LiteGraph.pointerevents_method+"up") { + } else if (e.type == LiteGraph.pointerevents_method + "up") { this.dragging = false; - LiteGraph.pointerListenerRemove(document,"move",this._binded_mouse_callback); - LiteGraph.pointerListenerRemove(document,"up",this._binded_mouse_callback); - LiteGraph.pointerListenerAdd(canvas,"move",this._binded_mouse_callback); - } else if ( is_inside && + LiteGraph.pointerListenerRemove( + document, + "move", + this._binded_mouse_callback + ); + LiteGraph.pointerListenerRemove( + document, + "up", + this._binded_mouse_callback + ); + LiteGraph.pointerListenerAdd( + canvas, + "move", + this._binded_mouse_callback + ); + } else if ( + is_inside && (e.type == "mousewheel" || - e.type == "wheel" || - e.type == "DOMMouseScroll") + e.type == "wheel" || + e.type == "DOMMouseScroll") ) { e.eventType = "mousewheel"; if (e.type == "wheel") { @@ -5217,35 +5435,34 @@ LGraphNode.prototype.executeAction = function(action) this.last_mouse[0] = x; this.last_mouse[1] = y; - if(is_inside) - { - e.preventDefault(); - e.stopPropagation(); - return false; - } + if (is_inside) { + e.preventDefault(); + e.stopPropagation(); + return false; + } }; - DragAndScale.prototype.toCanvasContext = function(ctx) { + DragAndScale.prototype.toCanvasContext = function (ctx) { ctx.scale(this.scale, this.scale); ctx.translate(this.offset[0], this.offset[1]); }; - DragAndScale.prototype.convertOffsetToCanvas = function(pos) { + DragAndScale.prototype.convertOffsetToCanvas = function (pos) { //return [pos[0] / this.scale - this.offset[0], pos[1] / this.scale - this.offset[1]]; return [ (pos[0] + this.offset[0]) * this.scale, - (pos[1] + this.offset[1]) * this.scale + (pos[1] + this.offset[1]) * this.scale, ]; }; - DragAndScale.prototype.convertCanvasToOffset = function(pos, out) { + DragAndScale.prototype.convertCanvasToOffset = function (pos, out) { out = out || [0, 0]; out[0] = pos[0] / this.scale - this.offset[0]; out[1] = pos[1] / this.scale - this.offset[1]; return out; }; - DragAndScale.prototype.mouseDrag = function(x, y) { + DragAndScale.prototype.mouseDrag = function (x, y) { this.offset[0] += x / this.scale; this.offset[1] += y / this.scale; @@ -5254,7 +5471,7 @@ LGraphNode.prototype.executeAction = function(action) } }; - DragAndScale.prototype.changeScale = function(value, zooming_center) { + DragAndScale.prototype.changeScale = function (value, zooming_center) { if (value < this.min_scale) { value = this.min_scale; } else if (value > this.max_scale) { @@ -5276,7 +5493,7 @@ LGraphNode.prototype.executeAction = function(action) zooming_center = zooming_center || [ rect.width * 0.5, - rect.height * 0.5 + rect.height * 0.5, ]; var center = this.convertCanvasToOffset(zooming_center); this.scale = value; @@ -5287,7 +5504,7 @@ LGraphNode.prototype.executeAction = function(action) var new_center = this.convertCanvasToOffset(zooming_center); var delta_offset = [ new_center[0] - center[0], - new_center[1] - center[1] + new_center[1] - center[1], ]; this.offset[0] += delta_offset[0]; @@ -5298,11 +5515,11 @@ LGraphNode.prototype.executeAction = function(action) } }; - DragAndScale.prototype.changeDeltaScale = function(value, zooming_center) { + DragAndScale.prototype.changeDeltaScale = function (value, zooming_center) { this.changeScale(this.scale * value, zooming_center); }; - DragAndScale.prototype.reset = function() { + DragAndScale.prototype.reset = function () { this.scale = 1; this.offset[0] = 0; this.offset[1] = 0; @@ -5345,13 +5562,13 @@ LGraphNode.prototype.executeAction = function(action) input_off: "#778", input_on: "#7F7", //"#BBD" output_off: "#778", - output_on: "#7F7" //"#BBD" - }; + output_on: "#7F7", //"#BBD" + }; this.default_connection_color_byType = { /*number: "#7F7", string: "#77F", boolean: "#F77",*/ - } + }; this.default_connection_color_byTypeOff = { /*number: "#474", string: "#447", @@ -5365,7 +5582,7 @@ LGraphNode.prototype.executeAction = function(action) this.clear_background = true; this.clear_background_color = "#222"; - this.read_only = false; //if set to true users cannot modify the graph + this.read_only = false; //if set to true users cannot modify the graph this.render_only_selected = true; this.live_mode = false; this.show_info = true; @@ -5375,14 +5592,14 @@ LGraphNode.prototype.executeAction = function(action) this.multi_select = false; //allow selecting multi nodes without pressing extra keys this.allow_searchbox = true; this.allow_reconnect_links = true; //allows to change a connection with having to redo it again - this.align_to_grid = false; //snap to grid + this.align_to_grid = false; //snap to grid this.drag_mode = false; this.dragging_rectangle = null; this.filter = null; //allows to filter to only accept some type of nodes in a graph - this.set_canvas_dirty_on_mouse_event = true; //forces to redraw the canvas if the mouse does anything + this.set_canvas_dirty_on_mouse_event = true; //forces to redraw the canvas if the mouse does anything this.always_render_background = false; this.render_shadows = true; this.render_canvas_border = true; @@ -5393,13 +5610,13 @@ LGraphNode.prototype.executeAction = function(action) this.render_collapsed_slots = true; this.render_execution_order = false; this.render_title_colored = true; - this.render_link_tooltip = true; + this.render_link_tooltip = true; this.links_render_mode = LiteGraph.SPLINE_LINK; this.mouse = [0, 0]; //mouse in canvas coordinates, where 0,0 is the top-left corner of the blue rectangle this.graph_mouse = [0, 0]; //mouse in graph coordinates, where 0,0 is the top-left corner of the blue rectangle - this.canvas_mouse = this.graph_mouse; //LEGACY: REMOVE THIS, USE GRAPH_MOUSE INSTEAD + this.canvas_mouse = this.graph_mouse; //LEGACY: REMOVE THIS, USE GRAPH_MOUSE INSTEAD //to personalize the search box this.onSearchBox = null; @@ -5410,31 +5627,31 @@ LGraphNode.prototype.executeAction = function(action) this.onDrawBackground = null; //to render background objects (behind nodes and connections) in the canvas affected by transform this.onDrawForeground = null; //to render foreground objects (above nodes and connections) in the canvas affected by transform this.onDrawOverlay = null; //to render foreground objects not affected by transform (for GUIs) - this.onDrawLinkTooltip = null; //called when rendering a tooltip - this.onNodeMoved = null; //called after moving a node - this.onSelectionChange = null; //called if the selection changes - this.onConnectingChange = null; //called before any link changes - this.onBeforeChange = null; //called before modifying the graph - this.onAfterChange = null; //called after modifying the graph + this.onDrawLinkTooltip = null; //called when rendering a tooltip + this.onNodeMoved = null; //called after moving a node + this.onSelectionChange = null; //called if the selection changes + this.onConnectingChange = null; //called before any link changes + this.onBeforeChange = null; //called before modifying the graph + this.onAfterChange = null; //called after modifying the graph this.connections_width = 3; this.round_radius = 8; this.current_node = null; this.node_widget = null; //used for widgets - this.over_link_center = null; + this.over_link_center = null; this.last_mouse_position = [0, 0]; this.visible_area = this.ds.visible_area; this.visible_links = []; - this.viewport = options.viewport || null; //to constraint render area to a portion of the canvas + this.viewport = options.viewport || null; //to constraint render area to a portion of the canvas //link canvas and graph if (graph) { graph.attachCanvas(this); } - this.setCanvas(canvas,options.skip_events); + this.setCanvas(canvas, options.skip_events); this.clear(); if (!options.skip_render) { @@ -5446,12 +5663,13 @@ LGraphNode.prototype.executeAction = function(action) global.LGraphCanvas = LiteGraph.LGraphCanvas = LGraphCanvas; - LGraphCanvas.DEFAULT_BACKGROUND_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII="; + LGraphCanvas.DEFAULT_BACKGROUND_IMAGE = + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII="; LGraphCanvas.link_type_colors = { "-1": LiteGraph.EVENT_LINK_COLOR, number: "#AAA", - node: "#DCA" + node: "#DCA", }; LGraphCanvas.gradients = {}; //cache of gradients @@ -5460,7 +5678,7 @@ LGraphNode.prototype.executeAction = function(action) * * @method clear */ - LGraphCanvas.prototype.clear = function() { + LGraphCanvas.prototype.clear = function () { this.frame = 0; this.last_draw_time = 0; this.render_time = 0; @@ -5481,7 +5699,7 @@ LGraphNode.prototype.executeAction = function(action) this.connecting_node = null; this.highlighted_links = {}; - this.dragging_canvas = false; + this.dragging_canvas = false; this.dirty_canvas = true; this.dirty_bgcanvas = true; @@ -5492,8 +5710,8 @@ LGraphNode.prototype.executeAction = function(action) this.last_mouse = [0, 0]; this.last_mouseclick = 0; - this.pointer_is_down = false; - this.pointer_is_double = false; + this.pointer_is_down = false; + this.pointer_is_double = false; this.visible_area.set([0, 0, 0, 0]); if (this.onClear) { @@ -5507,7 +5725,7 @@ LGraphNode.prototype.executeAction = function(action) * @method setGraph * @param {LGraph} graph */ - LGraphCanvas.prototype.setGraph = function(graph, skip_clear) { + LGraphCanvas.prototype.setGraph = function (graph, skip_clear) { if (this.graph == graph) { return; } @@ -5523,9 +5741,8 @@ LGraphNode.prototype.executeAction = function(action) graph.attachCanvas(this); - //remove the graph stack in case a subgraph was open - if (this._graph_stack) - this._graph_stack = null; + //remove the graph stack in case a subgraph was open + if (this._graph_stack) this._graph_stack = null; this.setDirty(true, true); }; @@ -5536,12 +5753,10 @@ LGraphNode.prototype.executeAction = function(action) * @method getTopGraph * @return {LGraph} graph */ - LGraphCanvas.prototype.getTopGraph = function() - { - if(this._graph_stack.length) - return this._graph_stack[0]; - return this.graph; - } + LGraphCanvas.prototype.getTopGraph = function () { + if (this._graph_stack.length) return this._graph_stack[0]; + return this.graph; + }; /** * opens a graph contained inside a node in the current graph @@ -5549,7 +5764,7 @@ LGraphNode.prototype.executeAction = function(action) * @method openSubgraph * @param {LGraph} graph */ - LGraphCanvas.prototype.openSubgraph = function(graph) { + LGraphCanvas.prototype.openSubgraph = function (graph) { if (!graph) { throw "graph cannot be null"; } @@ -5568,7 +5783,7 @@ LGraphNode.prototype.executeAction = function(action) } graph.attachCanvas(this); - this.checkPanels(); + this.checkPanels(); this.setDirty(true, true); }; @@ -5578,7 +5793,7 @@ LGraphNode.prototype.executeAction = function(action) * @method closeSubgraph * @param {LGraph} assigns a graph */ - LGraphCanvas.prototype.closeSubgraph = function() { + LGraphCanvas.prototype.closeSubgraph = function () { if (!this._graph_stack || this._graph_stack.length == 0) { return; } @@ -5593,8 +5808,8 @@ LGraphNode.prototype.executeAction = function(action) this.selectNodes([subgraph_node]); } // when close sub graph back to offset [0, 0] scale 1 - this.ds.offset = [0, 0] - this.ds.scale = 1 + this.ds.offset = [0, 0]; + this.ds.scale = 1; }; /** @@ -5602,7 +5817,7 @@ LGraphNode.prototype.executeAction = function(action) * @method getCurrentGraph * @return {LGraph} the active graph */ - LGraphCanvas.prototype.getCurrentGraph = function() { + LGraphCanvas.prototype.getCurrentGraph = function () { return this.graph; }; @@ -5612,7 +5827,7 @@ LGraphNode.prototype.executeAction = function(action) * @method setCanvas * @param {Canvas} assigns a canvas (also accepts the ID of the element (not a selector) */ - LGraphCanvas.prototype.setCanvas = function(canvas, skip_events) { + LGraphCanvas.prototype.setCanvas = function (canvas, skip_events) { var that = this; if (canvas) { @@ -5657,8 +5872,10 @@ LGraphNode.prototype.executeAction = function(action) if (canvas.getContext == null) { if (canvas.localName != "canvas") { - throw "Element supplied for LGraphCanvas must be a element, you passed a " + - canvas.localName; + throw ( + "Element supplied for LGraphCanvas must be a element, you passed a " + + canvas.localName + ); } throw "This browser doesn't support Canvas"; } @@ -5684,7 +5901,7 @@ LGraphNode.prototype.executeAction = function(action) //used in some events to capture them LGraphCanvas.prototype._doNothing = function doNothing(e) { - //console.log("pointerevents: _doNothing "+e.type); + //console.log("pointerevents: _doNothing "+e.type); e.preventDefault(); return false; }; @@ -5697,14 +5914,14 @@ LGraphNode.prototype.executeAction = function(action) * binds mouse, keyboard, touch and drag events to the canvas * @method bindEvents **/ - LGraphCanvas.prototype.bindEvents = function() { + LGraphCanvas.prototype.bindEvents = function () { if (this._events_binded) { console.warn("LGraphCanvas: events already binded"); return; } //console.log("pointerevents: bindEvents"); - + var canvas = this.canvas; var ref_window = this.getCanvasWindow(); @@ -5715,16 +5932,26 @@ LGraphNode.prototype.executeAction = function(action) // why mousemove and mouseup were not binded here? this._mousemove_callback = this.processMouseMove.bind(this); this._mouseup_callback = this.processMouseUp.bind(this); - + //touch events -- TODO IMPLEMENT //this._touch_callback = this.touchHandler.bind(this); - LiteGraph.pointerListenerAdd(canvas,"down", this._mousedown_callback, true); //down do not need to store the binded + LiteGraph.pointerListenerAdd( + canvas, + "down", + this._mousedown_callback, + true + ); //down do not need to store the binded canvas.addEventListener("mousewheel", this._mousewheel_callback, false); - LiteGraph.pointerListenerAdd(canvas,"up", this._mouseup_callback, true); // CHECK: ??? binded or not - LiteGraph.pointerListenerAdd(canvas,"move", this._mousemove_callback); - + LiteGraph.pointerListenerAdd( + canvas, + "up", + this._mouseup_callback, + true + ); // CHECK: ??? binded or not + LiteGraph.pointerListenerAdd(canvas, "move", this._mousemove_callback); + canvas.addEventListener("contextmenu", this._doNothing); canvas.addEventListener( "DOMMouseScroll", @@ -5743,7 +5970,7 @@ LGraphNode.prototype.executeAction = function(action) //Keyboard ****************** this._key_callback = this.processKey.bind(this); - canvas.setAttribute("tabindex",1); //otherwise key events are ignored + canvas.setAttribute("tabindex", 1); //otherwise key events are ignored canvas.addEventListener("keydown", this._key_callback, true); document.addEventListener("keyup", this._key_callback, true); //in document, otherwise it doesn't fire keyup @@ -5762,20 +5989,32 @@ LGraphNode.prototype.executeAction = function(action) * unbinds mouse events from the canvas * @method unbindEvents **/ - LGraphCanvas.prototype.unbindEvents = function() { + LGraphCanvas.prototype.unbindEvents = function () { if (!this._events_binded) { console.warn("LGraphCanvas: no events binded"); return; } //console.log("pointerevents: unbindEvents"); - + var ref_window = this.getCanvasWindow(); var document = ref_window.document; - LiteGraph.pointerListenerRemove(this.canvas,"move", this._mousedown_callback); - LiteGraph.pointerListenerRemove(this.canvas,"up", this._mousedown_callback); - LiteGraph.pointerListenerRemove(this.canvas,"down", this._mousedown_callback); + LiteGraph.pointerListenerRemove( + this.canvas, + "move", + this._mousedown_callback + ); + LiteGraph.pointerListenerRemove( + this.canvas, + "up", + this._mousedown_callback + ); + LiteGraph.pointerListenerRemove( + this.canvas, + "down", + this._mousedown_callback + ); this.canvas.removeEventListener( "mousewheel", this._mousewheel_callback @@ -5804,7 +6043,7 @@ LGraphNode.prototype.executeAction = function(action) this._events_binded = false; }; - LGraphCanvas.getFileExtension = function(url) { + LGraphCanvas.getFileExtension = function (url) { var question = url.indexOf("?"); if (question != -1) { url = url.substr(0, question); @@ -5821,7 +6060,7 @@ LGraphNode.prototype.executeAction = function(action) * this is useful if you plant to render 3D objects inside your nodes, it uses litegl.js for webgl and canvas2DtoWebGL to emulate the Canvas2D calls in webGL * @method enableWebGL **/ - LGraphCanvas.prototype.enableWebGL = function() { + LGraphCanvas.prototype.enableWebGL = function () { if (typeof GL === "undefined") { throw "litegl.js must be included to use a WebGL canvas"; } @@ -5850,7 +6089,7 @@ LGraphNode.prototype.executeAction = function(action) * @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) { + LGraphCanvas.prototype.setDirty = function (fgcanvas, bgcanvas) { if (fgcanvas) { this.dirty_canvas = true; } @@ -5865,7 +6104,7 @@ LGraphNode.prototype.executeAction = function(action) * @method getCanvasWindow * @return {window} returns the window where the canvas is attached (the DOM root node) */ - LGraphCanvas.prototype.getCanvasWindow = function() { + LGraphCanvas.prototype.getCanvasWindow = function () { if (!this.canvas) { return window; } @@ -5878,7 +6117,7 @@ LGraphNode.prototype.executeAction = function(action) * * @method startRendering */ - LGraphCanvas.prototype.startRendering = function() { + LGraphCanvas.prototype.startRendering = function () { if (this.is_rendering) { return; } //already rendering @@ -5903,7 +6142,7 @@ LGraphNode.prototype.executeAction = function(action) * * @method stopRendering */ - LGraphCanvas.prototype.stopRendering = function() { + LGraphCanvas.prototype.stopRendering = function () { this.is_rendering = false; /* if(this.rendering_timer_id) @@ -5916,19 +6155,16 @@ LGraphNode.prototype.executeAction = function(action) /* LiteGraphCanvas input */ - //used to block future mouse events (because of im gui) - LGraphCanvas.prototype.blockClick = function() - { - this.block_click = true; - this.last_mouseclick = 0; - } - - LGraphCanvas.prototype.processMouseDown = function(e) { - - if( this.set_canvas_dirty_on_mouse_event ) - this.dirty_canvas = true; - - if (!this.graph) { + //used to block future mouse events (because of im gui) + LGraphCanvas.prototype.blockClick = function () { + this.block_click = true; + this.last_mouseclick = 0; + }; + + LGraphCanvas.prototype.processMouseDown = function (e) { + if (this.set_canvas_dirty_on_mouse_event) this.dirty_canvas = true; + + if (!this.graph) { return; } @@ -5939,62 +6175,81 @@ LGraphNode.prototype.executeAction = function(action) LGraphCanvas.active_canvas = this; var that = this; - var x = e.clientX; - var y = e.clientY; - //console.log(y,this.viewport); - //console.log("pointerevents: processMouseDown pointerId:"+e.pointerId+" which:"+e.which+" isPrimary:"+e.isPrimary+" :: x y "+x+" "+y); + var x = e.clientX; + var y = e.clientY; + //console.log(y,this.viewport); + //console.log("pointerevents: processMouseDown pointerId:"+e.pointerId+" which:"+e.which+" isPrimary:"+e.isPrimary+" :: x y "+x+" "+y); - this.ds.viewport = this.viewport; - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); + this.ds.viewport = this.viewport; + var is_inside = + !this.viewport || + (this.viewport && + x >= this.viewport[0] && + x < this.viewport[0] + this.viewport[2] && + y >= this.viewport[1] && + y < this.viewport[1] + this.viewport[3]); //move mouse move event to the window in case it drags outside of the canvas - if(!this.options.skip_events) - { - LiteGraph.pointerListenerRemove(this.canvas,"move", this._mousemove_callback); - LiteGraph.pointerListenerAdd(ref_window.document,"move", this._mousemove_callback,true); //catch for the entire window - LiteGraph.pointerListenerAdd(ref_window.document,"up", this._mouseup_callback,true); - } - - if(!is_inside){ - return; - } - - var node = this.graph.getNodeOnPos( e.canvasX, e.canvasY, this.visible_nodes, 5 ); + if (!this.options.skip_events) { + LiteGraph.pointerListenerRemove( + this.canvas, + "move", + this._mousemove_callback + ); + LiteGraph.pointerListenerAdd( + ref_window.document, + "move", + this._mousemove_callback, + true + ); //catch for the entire window + LiteGraph.pointerListenerAdd( + ref_window.document, + "up", + this._mouseup_callback, + true + ); + } + + if (!is_inside) { + return; + } + + var node = this.graph.getNodeOnPos( + e.canvasX, + e.canvasY, + this.visible_nodes, + 5 + ); var skip_dragging = false; var skip_action = false; var now = LiteGraph.getTime(); - var is_primary = (e.isPrimary === undefined || !e.isPrimary); - var is_double_click = (now - this.last_mouseclick < 300) && is_primary; - this.mouse[0] = e.clientX; - this.mouse[1] = e.clientY; + var is_primary = e.isPrimary === undefined || !e.isPrimary; + var is_double_click = now - this.last_mouseclick < 300 && is_primary; + this.mouse[0] = e.clientX; + this.mouse[1] = e.clientY; this.graph_mouse[0] = e.canvasX; this.graph_mouse[1] = e.canvasY; - this.last_click_position = [this.mouse[0],this.mouse[1]]; - - if (this.pointer_is_down && is_primary ){ - this.pointer_is_double = true; - //console.log("pointerevents: pointer_is_double start"); - }else{ - this.pointer_is_double = false; - } - this.pointer_is_down = true; - - + this.last_click_position = [this.mouse[0], this.mouse[1]]; + + if (this.pointer_is_down && is_primary) { + this.pointer_is_double = true; + //console.log("pointerevents: pointer_is_double start"); + } else { + this.pointer_is_double = false; + } + this.pointer_is_down = true; + this.canvas.focus(); LiteGraph.closeAllContextMenus(ref_window); - if (this.onMouse) - { - if (this.onMouse(e) == true) - return; + if (this.onMouse) { + if (this.onMouse(e) == true) return; } - //left button mouse / single finger - if (e.which == 1 && !this.pointer_is_double) - { - if (e.ctrlKey) - { + //left button mouse / single finger + if (e.which == 1 && !this.pointer_is_double) { + if (e.ctrlKey) { this.dragging_rectangle = new Float32Array(4); this.dragging_rectangle[0] = e.canvasX; this.dragging_rectangle[1] = e.canvasY; @@ -6004,17 +6259,23 @@ LGraphNode.prototype.executeAction = function(action) } // clone node ALT dragging - if (LiteGraph.alt_drag_do_clone_nodes && e.altKey && node && this.allow_interaction && !skip_action && !this.read_only) - { - if (cloned = node.clone()){ + if ( + LiteGraph.alt_drag_do_clone_nodes && + e.altKey && + node && + this.allow_interaction && + !skip_action && + !this.read_only + ) { + if ((cloned = node.clone())) { cloned.pos[0] += 5; cloned.pos[1] += 5; - this.graph.add(cloned,false,{doCalcSize: false}); + this.graph.add(cloned, false, { doCalcSize: false }); node = cloned; skip_action = true; if (!block_drag_node) { if (this.allow_dragnodes) { - this.graph.beforeChange(); + this.graph.beforeChange(); this.node_dragged = node; } if (!this.selected_nodes[node.id]) { @@ -6023,22 +6284,34 @@ LGraphNode.prototype.executeAction = function(action) } } } - + var clicking_canvas_bg = false; //when clicked on top of a node //and it is not interactive - if (node && (this.allow_interaction || node.flags.allow_interaction) && !skip_action && !this.read_only) { + if ( + node && + (this.allow_interaction || node.flags.allow_interaction) && + !skip_action && + !this.read_only + ) { if (!this.live_mode && !node.flags.pinned) { this.bringToFront(node); } //if it wasn't selected? //not dragging mouse to connect two slots - if ( this.allow_interaction && !this.connecting_node && !node.flags.collapsed && !this.live_mode ) { + if ( + this.allow_interaction && + !this.connecting_node && + !node.flags.collapsed && + !this.live_mode + ) { //Search for corner for resize - if ( !skip_action && + if ( + !skip_action && node.resizable !== false && - isInsideRectangle( e.canvasX, + isInsideRectangle( + e.canvasX, e.canvasY, node.pos[0] + node.size[0] - 5, node.pos[1] + node.size[1] - 5, @@ -6046,14 +6319,18 @@ LGraphNode.prototype.executeAction = function(action) 10 ) ) { - this.graph.beforeChange(); + this.graph.beforeChange(); this.resizing_node = node; this.canvas.style.cursor = "se-resize"; skip_action = true; } else { //search for outputs if (node.outputs) { - for ( var i = 0, l = node.outputs.length; i < l; ++i ) { + for ( + var i = 0, l = node.outputs.length; + i < l; + ++i + ) { var output = node.outputs[i]; var link_pos = node.getConnectionPos(false, i); if ( @@ -6069,10 +6346,15 @@ LGraphNode.prototype.executeAction = function(action) this.connecting_node = node; this.connecting_output = output; this.connecting_output.slot_index = i; - this.connecting_pos = node.getConnectionPos( false, i ); + this.connecting_pos = node.getConnectionPos( + false, + i + ); this.connecting_slot = i; - if (LiteGraph.shift_click_do_break_link_from){ + if ( + LiteGraph.shift_click_do_break_link_from + ) { if (e.shiftKey) { node.disconnectOutput(i); } @@ -6096,7 +6378,11 @@ LGraphNode.prototype.executeAction = function(action) //search for inputs if (node.inputs) { - for ( var i = 0, l = node.inputs.length; i < l; ++i ) { + for ( + var i = 0, l = node.inputs.length; + i < l; + ++i + ) { var input = node.inputs[i]; var link_pos = node.getConnectionPos(true, i); if ( @@ -6120,52 +6406,58 @@ LGraphNode.prototype.executeAction = function(action) } if (input.link !== null) { - var link_info = this.graph.links[ - input.link - ]; //before disconnecting - if (LiteGraph.click_do_break_link_to){ + var link_info = + this.graph.links[input.link]; //before disconnecting + if (LiteGraph.click_do_break_link_to) { node.disconnectInput(i); this.dirty_bgcanvas = true; skip_action = true; - }else{ + } else { // do same action as has not node ? } if ( this.allow_reconnect_links || - //this.move_destination_link_without_shift || + //this.move_destination_link_without_shift || e.shiftKey ) { - if (!LiteGraph.click_do_break_link_to){ + if ( + !LiteGraph.click_do_break_link_to + ) { node.disconnectInput(i); } - this.connecting_node = this.graph._nodes_by_id[ - link_info.origin_id - ]; + this.connecting_node = + this.graph._nodes_by_id[ + link_info.origin_id + ]; this.connecting_slot = link_info.origin_slot; - this.connecting_output = this.connecting_node.outputs[ - this.connecting_slot - ]; - this.connecting_pos = this.connecting_node.getConnectionPos( false, this.connecting_slot ); - + this.connecting_output = + this.connecting_node.outputs[ + this.connecting_slot + ]; + this.connecting_pos = + this.connecting_node.getConnectionPos( + false, + this.connecting_slot + ); + this.dirty_bgcanvas = true; skip_action = true; } - - - }else{ + } else { // has not node } - - if (!skip_action){ + + if (!skip_action) { // connect from in to out, from to to from this.connecting_node = node; this.connecting_input = input; this.connecting_input.slot_index = i; - this.connecting_pos = node.getConnectionPos( true, i ); + this.connecting_pos = + node.getConnectionPos(true, i); this.connecting_slot = i; - + this.dirty_bgcanvas = true; skip_action = true; } @@ -6178,219 +6470,296 @@ LGraphNode.prototype.executeAction = function(action) //it wasn't clicked on the links boxes if (!skip_action) { var block_drag_node = false; - var pos = [e.canvasX - node.pos[0], e.canvasY - node.pos[1]]; + var pos = [ + e.canvasX - node.pos[0], + e.canvasY - node.pos[1], + ]; //widgets - var widget = this.processNodeWidgets( node, this.graph_mouse, e ); + var widget = this.processNodeWidgets( + node, + this.graph_mouse, + e + ); if (widget) { block_drag_node = true; this.node_widget = [node, widget]; } //double clicking - if (this.allow_interaction && is_double_click && this.selected_nodes[node.id]) { + if ( + this.allow_interaction && + is_double_click && + this.selected_nodes[node.id] + ) { //double click node if (node.onDblClick) { - node.onDblClick( e, pos, this ); + node.onDblClick(e, pos, this); } this.processNodeDblClicked(node); block_drag_node = true; } //if do not capture mouse - if ( node.onMouseDown && node.onMouseDown( e, pos, this ) ) { + if (node.onMouseDown && node.onMouseDown(e, pos, this)) { block_drag_node = true; } else { - //open subgraph button - if(node.subgraph && !node.skip_subgraph_button) - { - if ( !node.flags.collapsed && pos[0] > node.size[0] - LiteGraph.NODE_TITLE_HEIGHT && pos[1] < 0 ) { - var that = this; - setTimeout(function() { - that.openSubgraph(node.subgraph); - }, 10); - } - } - - if (this.live_mode) { - clicking_canvas_bg = true; - block_drag_node = true; - } + //open subgraph button + if (node.subgraph && !node.skip_subgraph_button) { + if ( + !node.flags.collapsed && + pos[0] > + node.size[0] - + LiteGraph.NODE_TITLE_HEIGHT && + pos[1] < 0 + ) { + var that = this; + setTimeout(function () { + that.openSubgraph(node.subgraph); + }, 10); + } + } + + if (this.live_mode) { + clicking_canvas_bg = true; + block_drag_node = true; + } } if (!block_drag_node) { if (this.allow_dragnodes) { - this.graph.beforeChange(); + this.graph.beforeChange(); this.node_dragged = node; } this.processNodeSelected(node, e); - } else { // double-click + } else { + // double-click /** * Don't call the function if the block is already selected. * Otherwise, it could cause the block to be unselected while its panel is open. */ - if (!node.is_selected) this.processNodeSelected(node, e); + if (!node.is_selected) + this.processNodeSelected(node, e); } this.dirty_canvas = true; } } //clicked outside of nodes else { - if (!skip_action){ - //search for link connector - if(!this.read_only) { - for (var i = 0; i < this.visible_links.length; ++i) { - var link = this.visible_links[i]; - var center = link._pos; - if ( - !center || - e.canvasX < center[0] - 4 || - e.canvasX > center[0] + 4 || - e.canvasY < center[1] - 4 || - e.canvasY > center[1] + 4 - ) { - continue; - } - //link clicked - this.showLinkMenu(link, e); - this.over_link_center = null; //clear tooltip - break; - } - } - - this.selected_group = this.graph.getGroupOnPos( e.canvasX, e.canvasY ); - this.selected_group_resizing = false; - if (this.selected_group && !this.read_only ) { - if (e.ctrlKey) { - this.dragging_rectangle = null; - } - - var dist = distance( [e.canvasX, e.canvasY], [ this.selected_group.pos[0] + this.selected_group.size[0], this.selected_group.pos[1] + this.selected_group.size[1] ] ); - if (dist * this.ds.scale < 10) { - this.selected_group_resizing = true; - } else { - this.selected_group.recomputeInsideNodes(); - } - } - - if (is_double_click && !this.read_only && this.allow_searchbox) { - this.showSearchBox(e); - e.preventDefault(); - e.stopPropagation(); - } - - clicking_canvas_bg = true; - } + if (!skip_action) { + //search for link connector + if (!this.read_only) { + for (var i = 0; i < this.visible_links.length; ++i) { + var link = this.visible_links[i]; + var center = link._pos; + if ( + !center || + e.canvasX < center[0] - 4 || + e.canvasX > center[0] + 4 || + e.canvasY < center[1] - 4 || + e.canvasY > center[1] + 4 + ) { + continue; + } + //link clicked + this.showLinkMenu(link, e); + this.over_link_center = null; //clear tooltip + break; + } + } + + this.selected_group = this.graph.getGroupOnPos( + e.canvasX, + e.canvasY + ); + this.selected_group_resizing = false; + if (this.selected_group && !this.read_only) { + if (e.ctrlKey) { + this.dragging_rectangle = null; + } + + var dist = distance( + [e.canvasX, e.canvasY], + [ + this.selected_group.pos[0] + + this.selected_group.size[0], + this.selected_group.pos[1] + + this.selected_group.size[1], + ] + ); + if (dist * this.ds.scale < 10) { + this.selected_group_resizing = true; + } else { + this.selected_group.recomputeInsideNodes(); + } + } + + if ( + is_double_click && + !this.read_only && + this.allow_searchbox + ) { + this.showSearchBox(e); + e.preventDefault(); + e.stopPropagation(); + } + + clicking_canvas_bg = true; + } } if (!skip_action && clicking_canvas_bg && this.allow_dragcanvas) { - //console.log("pointerevents: dragging_canvas start"); - this.dragging_canvas = true; + //console.log("pointerevents: dragging_canvas start"); + this.dragging_canvas = true; } - } else if (e.which == 2) { //middle button - - if (LiteGraph.middle_click_slot_add_default_node){ - if (node && this.allow_interaction && !skip_action && !this.read_only){ - //not dragging mouse to connect two slots - if ( - !this.connecting_node && - !node.flags.collapsed && - !this.live_mode - ) { - var mClikSlot = false; - var mClikSlot_index = false; - var mClikSlot_isOut = false; - //search for outputs - if (node.outputs) { - for ( var i = 0, l = node.outputs.length; i < l; ++i ) { - var output = node.outputs[i]; - var link_pos = node.getConnectionPos(false, i); - if (isInsideRectangle(e.canvasX,e.canvasY,link_pos[0] - 15,link_pos[1] - 10,30,20)) { - mClikSlot = output; - mClikSlot_index = i; - mClikSlot_isOut = true; - break; - } - } - } - - //search for inputs - 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(e.canvasX,e.canvasY,link_pos[0] - 15,link_pos[1] - 10,30,20)) { - mClikSlot = input; - mClikSlot_index = i; - mClikSlot_isOut = false; - break; - } - } - } - //console.log("middleClickSlots? "+mClikSlot+" & "+(mClikSlot_index!==false)); - if (mClikSlot && mClikSlot_index!==false){ - - var alphaPosY = 0.5-((mClikSlot_index+1)/((mClikSlot_isOut?node.outputs.length:node.inputs.length))); - var node_bounding = node.getBounding(); - // estimate a position: this is a bad semi-bad-working mess .. REFACTOR with a correct autoplacement that knows about the others slots and nodes - var posRef = [ (!mClikSlot_isOut?node_bounding[0]:node_bounding[0]+node_bounding[2])// + node_bounding[0]/this.canvas.width*150 - ,e.canvasY-80// + node_bounding[0]/this.canvas.width*66 // vertical "derive" - ]; - var nodeCreated = this.createDefaultNodeForSlot({ nodeFrom: !mClikSlot_isOut?null:node - ,slotFrom: !mClikSlot_isOut?null:mClikSlot_index - ,nodeTo: !mClikSlot_isOut?node:null - ,slotTo: !mClikSlot_isOut?mClikSlot_index:null - ,position: posRef //,e: e - ,nodeType: "AUTO" //nodeNewType - ,posAdd:[!mClikSlot_isOut?-30:30, -alphaPosY*130] //-alphaPosY*30] - ,posSizeFix:[!mClikSlot_isOut?-1:0, 0] //-alphaPosY*2*/ - }); - - } - } - } - } else if (!skip_action && this.allow_dragcanvas) { - //console.log("pointerevents: dragging_canvas start from middle button"); - this.dragging_canvas = true; - } - - - } else if (e.which == 3 || this.pointer_is_double) { - - //right button - if (this.allow_interaction && !skip_action && !this.read_only){ - - // is it hover a node ? - if (node){ - if(Object.keys(this.selected_nodes).length - && (this.selected_nodes[node.id] || e.shiftKey || e.ctrlKey || e.metaKey) - ){ - // is multiselected or using shift to include the now node - if (!this.selected_nodes[node.id]) this.selectNodes([node],true); // add this if not present - }else{ - // update selection - this.selectNodes([node]); - } - } - - // show menu on this node - this.processContextMenu(node, e); - } - - } - //TODO - //if(this.node_selected != prev_selected) - // this.onNodeSelectionChange(this.node_selected); - - this.last_mouse[0] = e.clientX; - this.last_mouse[1] = e.clientY; - this.last_mouseclick = LiteGraph.getTime(); - this.last_mouse_dragging = true; + if (LiteGraph.middle_click_slot_add_default_node) { + if ( + node && + this.allow_interaction && + !skip_action && + !this.read_only + ) { + //not dragging mouse to connect two slots + if ( + !this.connecting_node && + !node.flags.collapsed && + !this.live_mode + ) { + var mClikSlot = false; + var mClikSlot_index = false; + var mClikSlot_isOut = false; + //search for outputs + if (node.outputs) { + for ( + var i = 0, l = node.outputs.length; + i < l; + ++i + ) { + var output = node.outputs[i]; + var link_pos = node.getConnectionPos(false, i); + if ( + isInsideRectangle( + e.canvasX, + e.canvasY, + link_pos[0] - 15, + link_pos[1] - 10, + 30, + 20 + ) + ) { + mClikSlot = output; + mClikSlot_index = i; + mClikSlot_isOut = true; + break; + } + } + } - /* + //search for inputs + 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( + e.canvasX, + e.canvasY, + link_pos[0] - 15, + link_pos[1] - 10, + 30, + 20 + ) + ) { + mClikSlot = input; + mClikSlot_index = i; + mClikSlot_isOut = false; + break; + } + } + } + //console.log("middleClickSlots? "+mClikSlot+" & "+(mClikSlot_index!==false)); + if (mClikSlot && mClikSlot_index !== false) { + var alphaPosY = + 0.5 - + (mClikSlot_index + 1) / + (mClikSlot_isOut + ? node.outputs.length + : node.inputs.length); + var node_bounding = node.getBounding(); + // estimate a position: this is a bad semi-bad-working mess .. REFACTOR with a correct autoplacement that knows about the others slots and nodes + var posRef = [ + !mClikSlot_isOut + ? node_bounding[0] + : node_bounding[0] + node_bounding[2], // + node_bounding[0]/this.canvas.width*150 + e.canvasY - 80, // + node_bounding[0]/this.canvas.width*66 // vertical "derive" + ]; + var nodeCreated = this.createDefaultNodeForSlot({ + nodeFrom: !mClikSlot_isOut ? null : node, + slotFrom: !mClikSlot_isOut + ? null + : mClikSlot_index, + nodeTo: !mClikSlot_isOut ? node : null, + slotTo: !mClikSlot_isOut + ? mClikSlot_index + : null, + position: posRef, //,e: e + nodeType: "AUTO", //nodeNewType + posAdd: [ + !mClikSlot_isOut ? -30 : 30, + -alphaPosY * 130, + ], //-alphaPosY*30] + posSizeFix: [!mClikSlot_isOut ? -1 : 0, 0], //-alphaPosY*2*/ + }); + } + } + } + } else if (!skip_action && this.allow_dragcanvas) { + //console.log("pointerevents: dragging_canvas start from middle button"); + this.dragging_canvas = true; + } + } else if (e.which == 3 || this.pointer_is_double) { + //right button + if (this.allow_interaction && !skip_action && !this.read_only) { + // is it hover a node ? + if (node) { + if ( + Object.keys(this.selected_nodes).length && + (this.selected_nodes[node.id] || + e.shiftKey || + e.ctrlKey || + e.metaKey) + ) { + // is multiselected or using shift to include the now node + if (!this.selected_nodes[node.id]) + this.selectNodes([node], true); // add this if not present + } else { + // update selection + this.selectNodes([node]); + } + } + + // show menu on this node + this.processContextMenu(node, e); + } + } + + //TODO + //if(this.node_selected != prev_selected) + // this.onNodeSelectionChange(this.node_selected); + + this.last_mouse[0] = e.clientX; + this.last_mouse[1] = e.clientY; + this.last_mouseclick = LiteGraph.getTime(); + this.last_mouse_dragging = true; + + /* if( (this.dirty_canvas || this.dirty_bgcanvas) && this.rendering_timer_id == null) this.draw(); */ @@ -6420,13 +6789,12 @@ LGraphNode.prototype.executeAction = function(action) * Called when a mouse move event has to be processed * @method processMouseMove **/ - LGraphCanvas.prototype.processMouseMove = function(e) { + LGraphCanvas.prototype.processMouseMove = function (e) { if (this.autoresize) { this.resize(); } - if( this.set_canvas_dirty_on_mouse_event ) - this.dirty_canvas = true; + if (this.set_canvas_dirty_on_mouse_event) this.dirty_canvas = true; if (!this.graph) { return; @@ -6435,24 +6803,23 @@ LGraphNode.prototype.executeAction = function(action) LGraphCanvas.active_canvas = this; this.adjustMouseEvent(e); var mouse = [e.clientX, e.clientY]; - this.mouse[0] = mouse[0]; - this.mouse[1] = mouse[1]; + this.mouse[0] = mouse[0]; + this.mouse[1] = mouse[1]; var delta = [ mouse[0] - this.last_mouse[0], - mouse[1] - this.last_mouse[1] + mouse[1] - this.last_mouse[1], ]; this.last_mouse = mouse; this.graph_mouse[0] = e.canvasX; this.graph_mouse[1] = e.canvasY; //console.log("pointerevents: processMouseMove "+e.pointerId+" "+e.isPrimary); - - if(this.block_click) - { - //console.log("pointerevents: processMouseMove block_click"); - e.preventDefault(); - return false; - } + + if (this.block_click) { + //console.log("pointerevents: processMouseMove block_click"); + e.preventDefault(); + return false; + } e.dragging = this.last_mouse_dragging; @@ -6467,21 +6834,22 @@ LGraphNode.prototype.executeAction = function(action) } //get node over - var node = this.graph.getNodeOnPos(e.canvasX,e.canvasY,this.visible_nodes); + var node = this.graph.getNodeOnPos( + e.canvasX, + e.canvasY, + this.visible_nodes + ); - if (this.dragging_rectangle) - { + if (this.dragging_rectangle) { this.dragging_rectangle[2] = e.canvasX - this.dragging_rectangle[0]; this.dragging_rectangle[3] = e.canvasY - this.dragging_rectangle[1]; this.dirty_canvas = true; - } - else if (this.selected_group && !this.read_only) - { + } else if (this.selected_group && !this.read_only) { //moving/resizing a group if (this.selected_group_resizing) { this.selected_group.size = [ e.canvasX - this.selected_group.pos[0], - e.canvasY - this.selected_group.pos[1] + e.canvasY - this.selected_group.pos[1], ]; } else { var deltax = delta[0] / this.ds.scale; @@ -6493,19 +6861,26 @@ LGraphNode.prototype.executeAction = function(action) } this.dirty_bgcanvas = true; } else if (this.dragging_canvas) { - ////console.log("pointerevents: processMouseMove is dragging_canvas"); + ////console.log("pointerevents: processMouseMove is dragging_canvas"); this.ds.offset[0] += delta[0] / this.ds.scale; this.ds.offset[1] += delta[1] / this.ds.scale; this.dirty_canvas = true; this.dirty_bgcanvas = true; - } else if ((this.allow_interaction || (node && node.flags.allow_interaction)) && !this.read_only) { + } else if ( + (this.allow_interaction || + (node && node.flags.allow_interaction)) && + !this.read_only + ) { if (this.connecting_node) { this.dirty_canvas = true; } //remove mouseover flag for (var i = 0, l = this.graph._nodes.length; i < l; ++i) { - if (this.graph._nodes[i].mouseOver && node != this.graph._nodes[i] ) { + if ( + this.graph._nodes[i].mouseOver && + node != this.graph._nodes[i] + ) { //mouse leave this.graph._nodes[i].mouseOver = false; if (this.node_over && this.node_over.onMouseLeave) { @@ -6518,9 +6893,7 @@ LGraphNode.prototype.executeAction = function(action) //mouse over a node if (node) { - - if(node.redraw_on_mouse) - this.dirty_canvas = true; + if (node.redraw_on_mouse) this.dirty_canvas = true; //this.canvas.style.cursor = "move"; if (!node.mouseOver) { @@ -6536,14 +6909,16 @@ LGraphNode.prototype.executeAction = function(action) //in case the node wants to do something if (node.onMouseMove) { - node.onMouseMove( e, [e.canvasX - node.pos[0], e.canvasY - node.pos[1]], this ); + node.onMouseMove( + e, + [e.canvasX - node.pos[0], e.canvasY - node.pos[1]], + this + ); } //if dragging a link if (this.connecting_node) { - - if (this.connecting_output){ - + if (this.connecting_output) { var pos = this._highlight_input || [0, 0]; //to store the output of isOverNodeInput //on top of input @@ -6551,21 +6926,30 @@ LGraphNode.prototype.executeAction = function(action) //mouse on top of the corner box, don't know what to do } else { //check if I have a slot below de mouse - var slot = this.isOverNodeInput( node, e.canvasX, e.canvasY, pos ); + var slot = this.isOverNodeInput( + node, + e.canvasX, + e.canvasY, + pos + ); if (slot != -1 && node.inputs[slot]) { var slot_type = node.inputs[slot].type; - if ( LiteGraph.isValidConnection( this.connecting_output.type, slot_type ) ) { + if ( + LiteGraph.isValidConnection( + this.connecting_output.type, + slot_type + ) + ) { this._highlight_input = pos; - this._highlight_input_slot = node.inputs[slot]; // XXX CHECK THIS + this._highlight_input_slot = + node.inputs[slot]; // XXX CHECK THIS } } else { this._highlight_input = null; - this._highlight_input_slot = null; // XXX CHECK THIS + this._highlight_input_slot = null; // XXX CHECK THIS } } - - }else if(this.connecting_input){ - + } else if (this.connecting_input) { var pos = this._highlight_output || [0, 0]; //to store the output of isOverNodeOutput //on top of output @@ -6573,10 +6957,20 @@ LGraphNode.prototype.executeAction = function(action) //mouse on top of the corner box, don't know what to do } else { //check if I have a slot below de mouse - var slot = this.isOverNodeOutput( node, e.canvasX, e.canvasY, pos ); + var slot = this.isOverNodeOutput( + node, + e.canvasX, + e.canvasY, + pos + ); if (slot != -1 && node.outputs[slot]) { var slot_type = node.outputs[slot].type; - if ( LiteGraph.isValidConnection( this.connecting_input.type, slot_type ) ) { + if ( + LiteGraph.isValidConnection( + this.connecting_input.type, + slot_type + ) + ) { this._highlight_output = pos; } } else { @@ -6603,49 +6997,61 @@ LGraphNode.prototype.executeAction = function(action) this.canvas.style.cursor = "crosshair"; } } - } else { //not over a node + } else { + //not over a node //search for link connector - var over_link = null; - for (var i = 0; i < this.visible_links.length; ++i) { - var link = this.visible_links[i]; - var center = link._pos; - if ( - !center || - e.canvasX < center[0] - 4 || - e.canvasX > center[0] + 4 || - e.canvasY < center[1] - 4 || - e.canvasY > center[1] + 4 - ) { - continue; - } - over_link = link; - break; - } - if( over_link != this.over_link_center ) - { - this.over_link_center = over_link; - this.dirty_canvas = true; - } - - if (this.canvas) { - this.canvas.style.cursor = ""; - } - } //end - - //send event to node if capturing input (used with widgets that allow drag outside of the area of the node) - if ( this.node_capturing_input && this.node_capturing_input != node && this.node_capturing_input.onMouseMove ) { - this.node_capturing_input.onMouseMove(e,[e.canvasX - this.node_capturing_input.pos[0],e.canvasY - this.node_capturing_input.pos[1]], this); - } - - //node being dragged + var over_link = null; + for (var i = 0; i < this.visible_links.length; ++i) { + var link = this.visible_links[i]; + var center = link._pos; + if ( + !center || + e.canvasX < center[0] - 4 || + e.canvasX > center[0] + 4 || + e.canvasY < center[1] - 4 || + e.canvasY > center[1] + 4 + ) { + continue; + } + over_link = link; + break; + } + if (over_link != this.over_link_center) { + this.over_link_center = over_link; + this.dirty_canvas = true; + } + + if (this.canvas) { + this.canvas.style.cursor = ""; + } + } //end + + //send event to node if capturing input (used with widgets that allow drag outside of the area of the node) + if ( + this.node_capturing_input && + this.node_capturing_input != node && + this.node_capturing_input.onMouseMove + ) { + this.node_capturing_input.onMouseMove( + e, + [ + e.canvasX - this.node_capturing_input.pos[0], + e.canvasY - this.node_capturing_input.pos[1], + ], + this + ); + } + + //node being dragged if (this.node_dragged && !this.live_mode) { - //console.log("draggin!",this.selected_nodes); + //console.log("draggin!",this.selected_nodes); for (var i in this.selected_nodes) { var n = this.selected_nodes[i]; n.pos[0] += delta[0] / this.ds.scale; n.pos[1] += delta[1] / this.ds.scale; - if (!n.is_selected) this.processNodeSelected(n, e); /* + if (!n.is_selected) this.processNodeSelected(n, e); + /* * Don't call the function if the block is already selected. * Otherwise, it could cause the block to be unselected while dragging. */ @@ -6657,11 +7063,14 @@ LGraphNode.prototype.executeAction = function(action) if (this.resizing_node && !this.live_mode) { //convert mouse to node space - var desired_size = [ e.canvasX - this.resizing_node.pos[0], e.canvasY - this.resizing_node.pos[1] ]; - var min_size = this.resizing_node.computeSize(); - desired_size[0] = Math.max( min_size[0], desired_size[0] ); - desired_size[1] = Math.max( min_size[1], desired_size[1] ); - this.resizing_node.setSize( desired_size ); + var desired_size = [ + e.canvasX - this.resizing_node.pos[0], + e.canvasY - this.resizing_node.pos[1], + ]; + var min_size = this.resizing_node.computeSize(); + desired_size[0] = Math.max(min_size[0], desired_size[0]); + desired_size[1] = Math.max(min_size[1], desired_size[1]); + this.resizing_node.setSize(desired_size); this.canvas.style.cursor = "se-resize"; this.dirty_canvas = true; @@ -6677,59 +7086,71 @@ LGraphNode.prototype.executeAction = function(action) * Called when a mouse up event has to be processed * @method processMouseUp **/ - LGraphCanvas.prototype.processMouseUp = function(e) { - - var is_primary = ( e.isPrimary === undefined || e.isPrimary ); + LGraphCanvas.prototype.processMouseUp = function (e) { + var is_primary = e.isPrimary === undefined || e.isPrimary; - //early exit for extra pointer - if(!is_primary){ - /*e.stopPropagation(); + //early exit for extra pointer + if (!is_primary) { + /*e.stopPropagation(); e.preventDefault();*/ - //console.log("pointerevents: processMouseUp pointerN_stop "+e.pointerId+" "+e.isPrimary); - return false; - } - - //console.log("pointerevents: processMouseUp "+e.pointerId+" "+e.isPrimary+" :: "+e.clientX+" "+e.clientY); - - if( this.set_canvas_dirty_on_mouse_event ) - this.dirty_canvas = true; - - if (!this.graph) - return; + //console.log("pointerevents: processMouseUp pointerN_stop "+e.pointerId+" "+e.isPrimary); + return false; + } + + //console.log("pointerevents: processMouseUp "+e.pointerId+" "+e.isPrimary+" :: "+e.clientX+" "+e.clientY); + + if (this.set_canvas_dirty_on_mouse_event) this.dirty_canvas = true; + + if (!this.graph) return; var window = this.getCanvasWindow(); var document = window.document; LGraphCanvas.active_canvas = this; //restore the mousemove event back to the canvas - if(!this.options.skip_events) - { - //console.log("pointerevents: processMouseUp adjustEventListener"); - LiteGraph.pointerListenerRemove(document,"move", this._mousemove_callback,true); - LiteGraph.pointerListenerAdd(this.canvas,"move", this._mousemove_callback,true); - LiteGraph.pointerListenerRemove(document,"up", this._mouseup_callback,true); - } + if (!this.options.skip_events) { + //console.log("pointerevents: processMouseUp adjustEventListener"); + LiteGraph.pointerListenerRemove( + document, + "move", + this._mousemove_callback, + true + ); + LiteGraph.pointerListenerAdd( + this.canvas, + "move", + this._mousemove_callback, + true + ); + LiteGraph.pointerListenerRemove( + document, + "up", + this._mouseup_callback, + true + ); + } this.adjustMouseEvent(e); var now = LiteGraph.getTime(); e.click_time = now - this.last_mouseclick; this.last_mouse_dragging = false; - this.last_click_position = null; + this.last_click_position = null; - if(this.block_click) - { - //console.log("pointerevents: processMouseUp block_clicks"); - this.block_click = false; //used to avoid sending twice a click in a immediate button - } + if (this.block_click) { + //console.log("pointerevents: processMouseUp block_clicks"); + this.block_click = false; //used to avoid sending twice a click in a immediate button + } - //console.log("pointerevents: processMouseUp which: "+e.which); - - if (e.which == 1) { + //console.log("pointerevents: processMouseUp which: "+e.which); - if( this.node_widget ) - { - this.processNodeWidgets( this.node_widget[0], this.graph_mouse, e ); - } + if (e.which == 1) { + if (this.node_widget) { + this.processNodeWidgets( + this.node_widget[0], + this.graph_mouse, + e + ); + } //left button this.node_widget = null; @@ -6755,17 +7176,17 @@ LGraphNode.prototype.executeAction = function(action) } this.selected_group_resizing = false; - var node = this.graph.getNodeOnPos( - e.canvasX, - e.canvasY, - this.visible_nodes - ); - + var node = this.graph.getNodeOnPos( + e.canvasX, + e.canvasY, + this.visible_nodes + ); + if (this.dragging_rectangle) { if (this.graph) { var nodes = this.graph._nodes; var node_bounding = new Float32Array(4); - + //compute bounding and flip if left to right var w = Math.abs(this.dragging_rectangle[2]); var h = Math.abs(this.dragging_rectangle[3]); @@ -6782,31 +7203,30 @@ LGraphNode.prototype.executeAction = function(action) this.dragging_rectangle[2] = w; this.dragging_rectangle[3] = h; - // test dragging rect size, if minimun simulate a click - if (!node || (w > 10 && h > 10 )){ - //test against all nodes (not visible because the rectangle maybe start outside - var to_select = []; - for (var i = 0; i < nodes.length; ++i) { - var nodeX = nodes[i]; - nodeX.getBounding(node_bounding); - if ( - !overlapBounding( - this.dragging_rectangle, - node_bounding - ) - ) { - continue; - } //out of the visible area - to_select.push(nodeX); - } - if (to_select.length) { - this.selectNodes(to_select,e.shiftKey); // add to selection with shift - } - }else{ - // will select of update selection - this.selectNodes([node],e.shiftKey||e.ctrlKey); // add to selection add to selection with ctrlKey or shiftKey - } - + // test dragging rect size, if minimun simulate a click + if (!node || (w > 10 && h > 10)) { + //test against all nodes (not visible because the rectangle maybe start outside + var to_select = []; + for (var i = 0; i < nodes.length; ++i) { + var nodeX = nodes[i]; + nodeX.getBounding(node_bounding); + if ( + !overlapBounding( + this.dragging_rectangle, + node_bounding + ) + ) { + continue; + } //out of the visible area + to_select.push(nodeX); + } + if (to_select.length) { + this.selectNodes(to_select, e.shiftKey); // add to selection with shift + } + } else { + // will select of update selection + this.selectNodes([node], e.shiftKey || e.ctrlKey); // add to selection add to selection with ctrlKey or shiftKey + } } this.dragging_rectangle = null; } else if (this.connecting_node) { @@ -6814,12 +7234,12 @@ LGraphNode.prototype.executeAction = function(action) this.dirty_canvas = true; this.dirty_bgcanvas = true; - var connInOrOut = this.connecting_output || this.connecting_input; + var connInOrOut = + this.connecting_output || this.connecting_input; var connType = connInOrOut.type; - + //node below mouse if (node) { - /* no need to condition on event type.. just another type if ( connType == LiteGraph.EVENT && @@ -6833,63 +7253,88 @@ LGraphNode.prototype.executeAction = function(action) ); } else {*/ - - //slot below mouse? connect - - if (this.connecting_output){ - - var slot = this.isOverNodeInput( + + //slot below mouse? connect + + if (this.connecting_output) { + var slot = this.isOverNodeInput( + node, + e.canvasX, + e.canvasY + ); + if (slot != -1) { + this.connecting_node.connect( + this.connecting_slot, node, - e.canvasX, - e.canvasY + slot ); - if (slot != -1) { - this.connecting_node.connect(this.connecting_slot, node, slot); - } else { - //not on top of an input - // look for a good slot - this.connecting_node.connectByType(this.connecting_slot,node,connType); - } - - }else if (this.connecting_input){ - - var slot = this.isOverNodeOutput( + } else { + //not on top of an input + // look for a good slot + this.connecting_node.connectByType( + this.connecting_slot, node, - e.canvasX, - e.canvasY + connType ); + } + } else if (this.connecting_input) { + var slot = this.isOverNodeOutput( + node, + e.canvasX, + e.canvasY + ); - if (slot != -1) { - node.connect(slot, this.connecting_node, this.connecting_slot); // this is inverted has output-input nature like - } else { - //not on top of an input - // look for a good slot - this.connecting_node.connectByTypeOutput(this.connecting_slot,node,connType); - } - + if (slot != -1) { + node.connect( + slot, + this.connecting_node, + this.connecting_slot + ); // this is inverted has output-input nature like + } else { + //not on top of an input + // look for a good slot + this.connecting_node.connectByTypeOutput( + this.connecting_slot, + node, + connType + ); } - - + } + //} - - }else{ - + } else { // add menu when releasing link in empty space - if (LiteGraph.release_link_on_empty_shows_menu){ - if (e.shiftKey && this.allow_searchbox){ - if(this.connecting_output){ - this.showSearchBox(e,{node_from: this.connecting_node, slot_from: this.connecting_output, type_filter_in: this.connecting_output.type}); - }else if(this.connecting_input){ - this.showSearchBox(e,{node_to: this.connecting_node, slot_from: this.connecting_input, type_filter_out: this.connecting_input.type}); - } - }else{ - if(this.connecting_output){ - this.showConnectionMenu({nodeFrom: this.connecting_node, slotFrom: this.connecting_output, e: e}); - }else if(this.connecting_input){ - this.showConnectionMenu({nodeTo: this.connecting_node, slotTo: this.connecting_input, e: e}); - } - } - } + if (LiteGraph.release_link_on_empty_shows_menu) { + if (e.shiftKey && this.allow_searchbox) { + if (this.connecting_output) { + this.showSearchBox(e, { + node_from: this.connecting_node, + slot_from: this.connecting_output, + type_filter_in: this.connecting_output.type, + }); + } else if (this.connecting_input) { + this.showSearchBox(e, { + node_to: this.connecting_node, + slot_from: this.connecting_input, + type_filter_out: this.connecting_input.type, + }); + } + } else { + if (this.connecting_output) { + this.showConnectionMenu({ + nodeFrom: this.connecting_node, + slotFrom: this.connecting_output, + e: e, + }); + } else if (this.connecting_input) { + this.showConnectionMenu({ + nodeTo: this.connecting_node, + slotTo: this.connecting_input, + e: e, + }); + } + } + } } this.connecting_output = null; @@ -6901,7 +7346,7 @@ LGraphNode.prototype.executeAction = function(action) else if (this.resizing_node) { this.dirty_canvas = true; this.dirty_bgcanvas = true; - this.graph.afterChange(this.resizing_node); + this.graph.afterChange(this.resizing_node); this.resizing_node = null; } else if (this.node_dragged) { //node being dragged? @@ -6909,7 +7354,14 @@ LGraphNode.prototype.executeAction = function(action) if ( node && e.click_time < 300 && - isInsideRectangle( e.canvasX, e.canvasY, node.pos[0], node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT, LiteGraph.NODE_TITLE_HEIGHT ) + isInsideRectangle( + e.canvasX, + e.canvasY, + node.pos[0], + node.pos[1] - LiteGraph.NODE_TITLE_HEIGHT, + LiteGraph.NODE_TITLE_HEIGHT, + LiteGraph.NODE_TITLE_HEIGHT + ) ) { node.collapse(); } @@ -6918,12 +7370,11 @@ LGraphNode.prototype.executeAction = function(action) 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.align_to_grid ) { + if (this.graph.config.align_to_grid || this.align_to_grid) { this.node_dragged.alignToGrid(); } - if( this.onNodeMoved ) - this.onNodeMoved( this.node_dragged ); - this.graph.afterChange(this.node_dragged); + if (this.onNodeMoved) this.onNodeMoved(this.node_dragged); + this.graph.afterChange(this.node_dragged); this.node_dragged = null; } //no node being dragged else { @@ -6942,7 +7393,14 @@ LGraphNode.prototype.executeAction = function(action) this.dragging_canvas = false; if (this.node_over && this.node_over.onMouseUp) { - this.node_over.onMouseUp( e, [ e.canvasX - this.node_over.pos[0], e.canvasY - this.node_over.pos[1] ], this ); + this.node_over.onMouseUp( + e, + [ + e.canvasX - this.node_over.pos[0], + e.canvasY - this.node_over.pos[1], + ], + this + ); } if ( this.node_capturing_input && @@ -6950,7 +7408,7 @@ LGraphNode.prototype.executeAction = function(action) ) { this.node_capturing_input.onMouseUp(e, [ e.canvasX - this.node_capturing_input.pos[0], - e.canvasY - this.node_capturing_input.pos[1] + e.canvasY - this.node_capturing_input.pos[1], ]); } } @@ -6971,12 +7429,11 @@ LGraphNode.prototype.executeAction = function(action) this.draw(); */ - if (is_primary) - { - this.pointer_is_down = false; - this.pointer_is_double = false; - } - + if (is_primary) { + this.pointer_is_down = false; + this.pointer_is_double = false; + } + this.graph.change(); //console.log("pointerevents: processMouseUp stopPropagation"); @@ -6989,7 +7446,7 @@ LGraphNode.prototype.executeAction = function(action) * Called when a mouse wheel event has to be processed * @method processMouseWheel **/ - LGraphCanvas.prototype.processMouseWheel = function(e) { + LGraphCanvas.prototype.processMouseWheel = function (e) { if (!this.graph || !this.allow_dragcanvas) { return; } @@ -6998,11 +7455,16 @@ LGraphNode.prototype.executeAction = function(action) this.adjustMouseEvent(e); - var x = e.clientX; - var y = e.clientY; - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); - if(!is_inside) - return; + var x = e.clientX; + var y = e.clientY; + var is_inside = + !this.viewport || + (this.viewport && + x >= this.viewport[0] && + x < this.viewport[0] + this.viewport[2] && + y >= this.viewport[1] && + y < this.viewport[1] + this.viewport[3]); + if (!is_inside) return; var scale = this.ds.scale; @@ -7025,7 +7487,7 @@ LGraphNode.prototype.executeAction = function(action) * returns true if a position (in graph space) is on top of a node little corner box * @method isOverNodeBox **/ - LGraphCanvas.prototype.isOverNodeBox = function(node, canvasx, canvasy) { + LGraphCanvas.prototype.isOverNodeBox = function (node, canvasx, canvasy) { var title_height = LiteGraph.NODE_TITLE_HEIGHT; if ( isInsideRectangle( @@ -7046,7 +7508,7 @@ LGraphNode.prototype.executeAction = function(action) * returns the INDEX if a position (in graph space) is on top of a node input slot * @method isOverNodeInput **/ - LGraphCanvas.prototype.isOverNodeInput = function( + LGraphCanvas.prototype.isOverNodeInput = function ( node, canvasx, canvasy, @@ -7087,12 +7549,12 @@ LGraphNode.prototype.executeAction = function(action) } return -1; }; - + /** * returns the INDEX if a position (in graph space) is on top of a node output slot * @method isOverNodeOuput **/ - LGraphCanvas.prototype.isOverNodeOutput = function( + LGraphCanvas.prototype.isOverNodeOutput = function ( node, canvasx, canvasy, @@ -7138,7 +7600,7 @@ LGraphNode.prototype.executeAction = function(action) * process a key event * @method processKey **/ - LGraphCanvas.prototype.processKey = function(e) { + LGraphCanvas.prototype.processKey = function (e) { if (!this.graph) { return; } @@ -7156,11 +7618,11 @@ LGraphNode.prototype.executeAction = function(action) this.dragging_canvas = true; block_default = true; } - + if (e.keyCode == 27) { //esc - if(this.node_panel) this.node_panel.close(); - if(this.options_panel) this.options_panel.close(); + if (this.node_panel) this.node_panel.close(); + if (this.options_panel) this.options_panel.close(); block_default = true; } @@ -7170,7 +7632,7 @@ LGraphNode.prototype.executeAction = function(action) block_default = true; } - if ((e.keyCode === 67) && (e.metaKey || e.ctrlKey) && !e.shiftKey) { + if (e.keyCode === 67 && (e.metaKey || e.ctrlKey) && !e.shiftKey) { //copy if (this.selected_nodes) { this.copyToClipboard(); @@ -7178,7 +7640,7 @@ LGraphNode.prototype.executeAction = function(action) } } - if ((e.keyCode === 86) && (e.metaKey || e.ctrlKey)) { + if (e.keyCode === 86 && (e.metaKey || e.ctrlKey)) { //paste this.pasteFromClipboard(e.shiftKey); } @@ -7229,17 +7691,16 @@ LGraphNode.prototype.executeAction = function(action) } }; - LGraphCanvas.prototype.copyToClipboard = function() { + LGraphCanvas.prototype.copyToClipboard = function () { var clipboard_info = { nodes: [], - links: [] + links: [], }; var index = 0; var selected_nodes_array = []; for (var i in this.selected_nodes) { var node = this.selected_nodes[i]; - if (node.clonable === false) - continue; + if (node.clonable === false) continue; node._relative_id = index; selected_nodes_array.push(node); index += 1; @@ -7247,12 +7708,10 @@ LGraphNode.prototype.executeAction = function(action) for (var i = 0; i < selected_nodes_array.length; ++i) { var node = selected_nodes_array[i]; - if(node.clonable === false) - continue; + if (node.clonable === false) continue; var cloned = node.clone(); - if(!cloned) - { - console.warn("node type not found: " + node.type ); + if (!cloned) { + console.warn("node type not found: " + node.type); continue; } clipboard_info.nodes.push(cloned.serialize()); @@ -7277,7 +7736,7 @@ LGraphNode.prototype.executeAction = function(action) link_info.origin_slot, //j, node._relative_id, link_info.target_slot, - target_node.id + target_node.id, ]); } } @@ -7288,9 +7747,14 @@ LGraphNode.prototype.executeAction = function(action) ); }; - LGraphCanvas.prototype.pasteFromClipboard = function(isConnectUnselected = false) { + LGraphCanvas.prototype.pasteFromClipboard = function ( + isConnectUnselected = false + ) { // if ctrl + shift + v is off, return when isConnectUnselected is true (shift is pressed) to maintain old behavior - if (!LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && isConnectUnselected) { + if ( + !LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && + isConnectUnselected + ) { return; } var data = localStorage.getItem("litegrapheditor_clipboard"); @@ -7298,7 +7762,7 @@ LGraphNode.prototype.executeAction = function(action) return; } - this.graph.beforeChange(); + this.graph.beforeChange(); //create nodes var clipboard_info = JSON.parse(data); @@ -7306,18 +7770,20 @@ LGraphNode.prototype.executeAction = function(action) var posMin = false; var posMinIndexes = false; for (var i = 0; i < clipboard_info.nodes.length; ++i) { - if (posMin){ - if(posMin[0]>clipboard_info.nodes[i].pos[0]){ + if (posMin) { + if (posMin[0] > clipboard_info.nodes[i].pos[0]) { posMin[0] = clipboard_info.nodes[i].pos[0]; posMinIndexes[0] = i; } - if(posMin[1]>clipboard_info.nodes[i].pos[1]){ + if (posMin[1] > clipboard_info.nodes[i].pos[1]) { posMin[1] = clipboard_info.nodes[i].pos[1]; posMinIndexes[1] = i; } - } - else{ - posMin = [clipboard_info.nodes[i].pos[0], clipboard_info.nodes[i].pos[1]]; + } else { + posMin = [ + clipboard_info.nodes[i].pos[0], + clipboard_info.nodes[i].pos[1], + ]; posMinIndexes = [i, i]; } } @@ -7327,13 +7793,13 @@ LGraphNode.prototype.executeAction = function(action) var node = LiteGraph.createNode(node_data.type); if (node) { node.configure(node_data); - - //paste in last known mouse position + + //paste in last known mouse position node.pos[0] += this.graph_mouse[0] - posMin[0]; //+= 5; node.pos[1] += this.graph_mouse[1] - posMin[1]; //+= 5; - this.graph.add(node,{doProcessChange:false}); - + this.graph.add(node, { doProcessChange: false }); + nodes.push(node); } } @@ -7345,42 +7811,49 @@ LGraphNode.prototype.executeAction = function(action) var origin_node_relative_id = link_info[0]; if (origin_node_relative_id != null) { origin_node = nodes[origin_node_relative_id]; - } else if (LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && isConnectUnselected) { + } else if ( + LiteGraph.ctrl_shift_v_paste_connect_unselected_outputs && + isConnectUnselected + ) { var origin_node_id = link_info[4]; if (origin_node_id) { origin_node = this.graph.getNodeById(origin_node_id); } } var target_node = nodes[link_info[2]]; - if( origin_node && target_node ) - origin_node.connect(link_info[1], target_node, link_info[3]); - else - console.warn("Warning, nodes missing on pasting"); + if (origin_node && target_node) + origin_node.connect(link_info[1], target_node, link_info[3]); + else console.warn("Warning, nodes missing on pasting"); } this.selectNodes(nodes); - this.graph.afterChange(); + this.graph.afterChange(); }; /** * process a item drop event on top the canvas * @method processDrop **/ - LGraphCanvas.prototype.processDrop = function(e) { + LGraphCanvas.prototype.processDrop = function (e) { e.preventDefault(); this.adjustMouseEvent(e); - var x = e.clientX; - var y = e.clientY; - var is_inside = !this.viewport || ( this.viewport && x >= this.viewport[0] && x < (this.viewport[0] + this.viewport[2]) && y >= this.viewport[1] && y < (this.viewport[1] + this.viewport[3]) ); - if(!is_inside){ - return; - // --- BREAK --- - } + var x = e.clientX; + var y = e.clientY; + var is_inside = + !this.viewport || + (this.viewport && + x >= this.viewport[0] && + x < this.viewport[0] + this.viewport[2] && + y >= this.viewport[1] && + y < this.viewport[1] + this.viewport[3]); + if (!is_inside) { + return; + // --- BREAK --- + } var pos = [e.canvasX, e.canvasY]; - var node = this.graph ? this.graph.getNodeOnPos(pos[0], pos[1]) : null; if (!node) { @@ -7410,7 +7883,7 @@ LGraphNode.prototype.executeAction = function(action) if (node.onDropData) { //prepare reader var reader = new FileReader(); - reader.onload = function(event) { + reader.onload = function (event) { //console.log(event.target); var data = event.target.result; node.onDropData(data, filename, file); @@ -7444,32 +7917,30 @@ LGraphNode.prototype.executeAction = function(action) }; //called if the graph doesn't have a default drop item behaviour - LGraphCanvas.prototype.checkDropItem = function(e) { + LGraphCanvas.prototype.checkDropItem = function (e) { if (e.dataTransfer.files.length) { var file = e.dataTransfer.files[0]; var ext = LGraphCanvas.getFileExtension(file.name).toLowerCase(); var nodetype = LiteGraph.node_types_by_file_extension[ext]; if (nodetype) { - this.graph.beforeChange(); + this.graph.beforeChange(); var node = LiteGraph.createNode(nodetype.type); node.pos = [e.canvasX, e.canvasY]; this.graph.add(node); if (node.onDropFile) { node.onDropFile(file); } - this.graph.afterChange(); + this.graph.afterChange(); } } }; - LGraphCanvas.prototype.processNodeDblClicked = function(n) { + LGraphCanvas.prototype.processNodeDblClicked = function (n) { if (this.onShowNodePanel) { this.onShowNodePanel(n); + } else { + this.showShowNodePanel(n); } - else - { - this.showShowNodePanel(n); - } if (this.onNodeDblClicked) { this.onNodeDblClicked(n); @@ -7478,8 +7949,11 @@ LGraphNode.prototype.executeAction = function(action) this.setDirty(true); }; - LGraphCanvas.prototype.processNodeSelected = function(node, e) { - this.selectNode(node, e && (e.shiftKey || e.ctrlKey || this.multi_select)); + LGraphCanvas.prototype.processNodeSelected = function (node, e) { + this.selectNode( + node, + e && (e.shiftKey || e.ctrlKey || this.multi_select) + ); if (this.onNodeSelected) { this.onNodeSelected(node); } @@ -7489,7 +7963,7 @@ LGraphNode.prototype.executeAction = function(action) * selects a given node (or adds it to the current selection) * @method selectNode **/ - LGraphCanvas.prototype.selectNode = function( + LGraphCanvas.prototype.selectNode = function ( node, add_to_current_selection ) { @@ -7504,14 +7978,16 @@ LGraphNode.prototype.executeAction = function(action) * selects several nodes (or adds them to the current selection) * @method selectNodes **/ - LGraphCanvas.prototype.selectNodes = function( nodes, add_to_current_selection ) - { - if (!add_to_current_selection) { + LGraphCanvas.prototype.selectNodes = function ( + nodes, + add_to_current_selection + ) { + if (!add_to_current_selection) { this.deselectAllNodes(); } nodes = nodes || this.graph._nodes; - if (typeof nodes == "string") nodes = [nodes]; + if (typeof nodes == "string") nodes = [nodes]; for (var i in nodes) { var node = nodes[i]; if (node.is_selected) { @@ -7542,8 +8018,7 @@ LGraphNode.prototype.executeAction = function(action) } } - if( this.onSelectionChange ) - this.onSelectionChange( this.selected_nodes ); + if (this.onSelectionChange) this.onSelectionChange(this.selected_nodes); this.setDirty(true); }; @@ -7552,7 +8027,7 @@ LGraphNode.prototype.executeAction = function(action) * removes a node from the current selection * @method deselectNode **/ - LGraphCanvas.prototype.deselectNode = function(node) { + LGraphCanvas.prototype.deselectNode = function (node) { if (!node.is_selected) { return; } @@ -7587,7 +8062,7 @@ LGraphNode.prototype.executeAction = function(action) * removes all nodes from the current selection * @method deselectAllNodes **/ - LGraphCanvas.prototype.deselectAllNodes = function() { + LGraphCanvas.prototype.deselectAllNodes = function () { if (!this.graph) { return; } @@ -7601,15 +8076,14 @@ LGraphNode.prototype.executeAction = function(action) node.onDeselected(); } node.is_selected = false; - if (this.onNodeDeselected) { - this.onNodeDeselected(node); - } + if (this.onNodeDeselected) { + this.onNodeDeselected(node); + } } this.selected_nodes = {}; this.current_node = null; this.highlighted_links = {}; - if( this.onSelectionChange ) - this.onSelectionChange( this.selected_nodes ); + if (this.onSelectionChange) this.onSelectionChange(this.selected_nodes); this.setDirty(true); }; @@ -7617,43 +8091,56 @@ LGraphNode.prototype.executeAction = function(action) * deletes all nodes in the current selection from the graph * @method deleteSelectedNodes **/ - LGraphCanvas.prototype.deleteSelectedNodes = function() { - - this.graph.beforeChange(); + LGraphCanvas.prototype.deleteSelectedNodes = function () { + this.graph.beforeChange(); for (var i in this.selected_nodes) { var node = this.selected_nodes[i]; - if(node.block_delete) - continue; + if (node.block_delete) continue; - //autoconnect when possible (very basic, only takes into account first input-output) - if(node.inputs && node.inputs.length && node.outputs && node.outputs.length && LiteGraph.isValidConnection( node.inputs[0].type, node.outputs[0].type ) && node.inputs[0].link && node.outputs[0].links && node.outputs[0].links.length ) - { - var input_link = node.graph.links[ node.inputs[0].link ]; - var output_link = node.graph.links[ node.outputs[0].links[0] ]; - var input_node = node.getInputNode(0); - var output_node = node.getOutputNodes(0)[0]; - if(input_node && output_node) - input_node.connect( input_link.origin_slot, output_node, output_link.target_slot ); - } + //autoconnect when possible (very basic, only takes into account first input-output) + if ( + node.inputs && + node.inputs.length && + node.outputs && + node.outputs.length && + LiteGraph.isValidConnection( + node.inputs[0].type, + node.outputs[0].type + ) && + node.inputs[0].link && + node.outputs[0].links && + node.outputs[0].links.length + ) { + var input_link = node.graph.links[node.inputs[0].link]; + var output_link = node.graph.links[node.outputs[0].links[0]]; + var input_node = node.getInputNode(0); + var output_node = node.getOutputNodes(0)[0]; + if (input_node && output_node) + input_node.connect( + input_link.origin_slot, + output_node, + output_link.target_slot + ); + } this.graph.remove(node); - if (this.onNodeDeselected) { - this.onNodeDeselected(node); - } + if (this.onNodeDeselected) { + this.onNodeDeselected(node); + } } this.selected_nodes = {}; this.current_node = null; this.highlighted_links = {}; this.setDirty(true); - this.graph.afterChange(); + this.graph.afterChange(); }; - + /** * centers the camera on a given node * @method centerOnNode **/ - LGraphCanvas.prototype.centerOnNode = function(node) { + LGraphCanvas.prototype.centerOnNode = function (node) { this.ds.offset[0] = -node.pos[0] - node.size[0] * 0.5 + @@ -7669,19 +8156,19 @@ LGraphNode.prototype.executeAction = function(action) * adds some useful properties to a mouse event, like the position in graph coordinates * @method adjustMouseEvent **/ - LGraphCanvas.prototype.adjustMouseEvent = function(e) { - var clientX_rel = 0; + LGraphCanvas.prototype.adjustMouseEvent = function (e) { + var clientX_rel = 0; var clientY_rel = 0; - - if (this.canvas) { + + if (this.canvas) { var b = this.canvas.getBoundingClientRect(); clientX_rel = e.clientX - b.left; clientY_rel = e.clientY - b.top; } else { - clientX_rel = e.clientX; - clientY_rel = e.clientY; + clientX_rel = e.clientX; + clientY_rel = e.clientY; } - + // e.deltaX = clientX_rel - this.last_mouse_position[0]; // e.deltaY = clientY_rel- this.last_mouse_position[1]; @@ -7690,7 +8177,7 @@ LGraphNode.prototype.executeAction = function(action) e.canvasX = clientX_rel / this.ds.scale - this.ds.offset[0]; e.canvasY = clientY_rel / this.ds.scale - this.ds.offset[1]; - + //console.log("pointerevents: adjustMouseEvent "+e.clientX+":"+e.clientY+" "+clientX_rel+":"+clientY_rel+" "+e.canvasX+":"+e.canvasY); }; @@ -7698,7 +8185,7 @@ LGraphNode.prototype.executeAction = function(action) * changes the zoom level of the graph (default is 1), you can pass also a place used to pivot the zoom * @method setZoom **/ - LGraphCanvas.prototype.setZoom = function(value, zooming_center) { + LGraphCanvas.prototype.setZoom = function (value, zooming_center) { this.ds.changeScale(value, zooming_center); /* if(!zooming_center && this.canvas) @@ -7728,7 +8215,7 @@ LGraphNode.prototype.executeAction = function(action) * converts a coordinate from graph coordinates to canvas2D coordinates * @method convertOffsetToCanvas **/ - LGraphCanvas.prototype.convertOffsetToCanvas = function(pos, out) { + LGraphCanvas.prototype.convertOffsetToCanvas = function (pos, out) { return this.ds.convertOffsetToCanvas(pos, out); }; @@ -7736,16 +8223,16 @@ LGraphNode.prototype.executeAction = function(action) * converts a coordinate from Canvas2D coordinates to graph space * @method convertCanvasToOffset **/ - LGraphCanvas.prototype.convertCanvasToOffset = function(pos, out) { + LGraphCanvas.prototype.convertCanvasToOffset = function (pos, out) { return this.ds.convertCanvasToOffset(pos, out); }; //converts event coordinates from canvas2D to graph coordinates - LGraphCanvas.prototype.convertEventToCanvasOffset = function(e) { + LGraphCanvas.prototype.convertEventToCanvasOffset = function (e) { var rect = this.canvas.getBoundingClientRect(); return this.convertCanvasToOffset([ e.clientX - rect.left, - e.clientY - rect.top + e.clientY - rect.top, ]); }; @@ -7753,7 +8240,7 @@ LGraphNode.prototype.executeAction = function(action) * brings a node to front (above all other nodes) * @method bringToFront **/ - LGraphCanvas.prototype.bringToFront = function(node) { + LGraphCanvas.prototype.bringToFront = function (node) { var i = this.graph._nodes.indexOf(node); if (i == -1) { return; @@ -7767,7 +8254,7 @@ LGraphNode.prototype.executeAction = function(action) * sends a node to the back (below all other nodes) * @method sendToBack **/ - LGraphCanvas.prototype.sendToBack = function(node) { + LGraphCanvas.prototype.sendToBack = function (node) { var i = this.graph._nodes.indexOf(node); if (i == -1) { return; @@ -7786,7 +8273,7 @@ LGraphNode.prototype.executeAction = function(action) * checks which nodes are visible (inside the camera area) * @method computeVisibleNodes **/ - LGraphCanvas.prototype.computeVisibleNodes = function(nodes, out) { + LGraphCanvas.prototype.computeVisibleNodes = function (nodes, out) { var visible_nodes = out || []; visible_nodes.length = 0; nodes = nodes || this.graph._nodes; @@ -7798,7 +8285,9 @@ LGraphNode.prototype.executeAction = function(action) continue; } - if (!overlapBounding(this.visible_area, n.getBounding(temp, true))) { + if ( + !overlapBounding(this.visible_area, n.getBounding(temp, true)) + ) { continue; } //out of the visible area @@ -7811,7 +8300,7 @@ LGraphNode.prototype.executeAction = function(action) * renders the whole canvas content, by rendering in two separated canvas, one containing the background grid and the connections, and one containing the nodes) * @method draw **/ - LGraphCanvas.prototype.draw = function(force_canvas, force_bgcanvas) { + LGraphCanvas.prototype.draw = function (force_canvas, force_bgcanvas) { if (!this.canvas || this.canvas.width == 0 || this.canvas.height == 0) { return; } @@ -7848,7 +8337,7 @@ LGraphNode.prototype.executeAction = function(action) * draws the front canvas (the one containing all the nodes) * @method drawFrontCanvas **/ - LGraphCanvas.prototype.drawFrontCanvas = function() { + LGraphCanvas.prototype.drawFrontCanvas = function () { this.dirty_canvas = false; if (!this.ctx) { @@ -7861,35 +8350,33 @@ LGraphNode.prototype.executeAction = function(action) } var canvas = this.canvas; - if ( ctx.start2D && !this.viewport ) { + if (ctx.start2D && !this.viewport) { ctx.start2D(); - ctx.restore(); - ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.restore(); + ctx.setTransform(1, 0, 0, 1, 0, 0); } //clip dirty area if there is one, otherwise work in full canvas - var area = this.viewport || this.dirty_area; + var area = this.viewport || this.dirty_area; if (area) { ctx.save(); ctx.beginPath(); - ctx.rect( area[0],area[1],area[2],area[3] ); + ctx.rect(area[0], area[1], area[2], area[3]); ctx.clip(); } //clear //canvas.width = canvas.width; if (this.clear_background) { - if(area) - ctx.clearRect( area[0],area[1],area[2],area[3] ); - else - ctx.clearRect(0, 0, canvas.width, canvas.height); + if (area) ctx.clearRect(area[0], area[1], area[2], area[3]); + else ctx.clearRect(0, 0, canvas.width, canvas.height); } //draw bg canvas if (this.bgcanvas == this.canvas) { this.drawBackCanvas(); } else { - ctx.drawImage( this.bgcanvas, 0, 0 ); + ctx.drawImage(this.bgcanvas, 0, 0); } //rendering @@ -7899,7 +8386,7 @@ LGraphNode.prototype.executeAction = function(action) //info widget if (this.show_info) { - this.renderInfo(ctx, area ? area[0] : 0, area ? area[1] : 0 ); + this.renderInfo(ctx, area ? area[0] : 0, area ? area[1] : 0); } if (this.graph) { @@ -7945,20 +8432,24 @@ LGraphNode.prototype.executeAction = function(action) if (this.connecting_pos != null) { ctx.lineWidth = this.connections_width; var link_color = null; - - var connInOrOut = this.connecting_output || this.connecting_input; + + var connInOrOut = + this.connecting_output || this.connecting_input; var connType = connInOrOut.type; var connDir = connInOrOut.dir; - if(connDir == null) - { - if (this.connecting_output) - connDir = this.connecting_node.horizontal ? LiteGraph.DOWN : LiteGraph.RIGHT; - else - connDir = this.connecting_node.horizontal ? LiteGraph.UP : LiteGraph.LEFT; - } + if (connDir == null) { + if (this.connecting_output) + connDir = this.connecting_node.horizontal + ? LiteGraph.DOWN + : LiteGraph.RIGHT; + else + connDir = this.connecting_node.horizontal + ? LiteGraph.UP + : LiteGraph.LEFT; + } var connShape = connInOrOut.shape; - + switch (connType) { case LiteGraph.EVENT: link_color = LiteGraph.EVENT_LINK_COLOR; @@ -7991,8 +8482,8 @@ LGraphNode.prototype.executeAction = function(action) 14, 10 ); - ctx.fill(); - ctx.beginPath(); + ctx.fill(); + ctx.beginPath(); ctx.rect( this.graph_mouse[0] - 6 + 0.5, this.graph_mouse[1] - 5 + 0.5, @@ -8000,12 +8491,20 @@ LGraphNode.prototype.executeAction = function(action) 10 ); } else if (connShape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(this.connecting_pos[0] + 8, this.connecting_pos[1] + 0.5); - ctx.lineTo(this.connecting_pos[0] - 4, this.connecting_pos[1] + 6 + 0.5); - ctx.lineTo(this.connecting_pos[0] - 4, this.connecting_pos[1] - 6 + 0.5); + ctx.moveTo( + this.connecting_pos[0] + 8, + this.connecting_pos[1] + 0.5 + ); + ctx.lineTo( + this.connecting_pos[0] - 4, + this.connecting_pos[1] + 6 + 0.5 + ); + ctx.lineTo( + this.connecting_pos[0] - 4, + this.connecting_pos[1] - 6 + 0.5 + ); ctx.closePath(); - } - else { + } else { ctx.arc( this.connecting_pos[0], this.connecting_pos[1], @@ -8013,8 +8512,8 @@ LGraphNode.prototype.executeAction = function(action) 0, Math.PI * 2 ); - ctx.fill(); - ctx.beginPath(); + ctx.fill(); + ctx.beginPath(); ctx.arc( this.graph_mouse[0], this.graph_mouse[1], @@ -8030,9 +8529,18 @@ LGraphNode.prototype.executeAction = function(action) ctx.beginPath(); var shape = this._highlight_input_slot.shape; if (shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(this._highlight_input[0] + 8, this._highlight_input[1] + 0.5); - ctx.lineTo(this._highlight_input[0] - 4, this._highlight_input[1] + 6 + 0.5); - ctx.lineTo(this._highlight_input[0] - 4, this._highlight_input[1] - 6 + 0.5); + ctx.moveTo( + this._highlight_input[0] + 8, + this._highlight_input[1] + 0.5 + ); + ctx.lineTo( + this._highlight_input[0] - 4, + this._highlight_input[1] + 6 + 0.5 + ); + ctx.lineTo( + this._highlight_input[0] - 4, + this._highlight_input[1] - 6 + 0.5 + ); ctx.closePath(); } else { ctx.arc( @@ -8048,9 +8556,18 @@ LGraphNode.prototype.executeAction = function(action) if (this._highlight_output) { ctx.beginPath(); if (shape === LiteGraph.ARROW_SHAPE) { - ctx.moveTo(this._highlight_output[0] + 8, this._highlight_output[1] + 0.5); - ctx.lineTo(this._highlight_output[0] - 4, this._highlight_output[1] + 6 + 0.5); - ctx.lineTo(this._highlight_output[0] - 4, this._highlight_output[1] - 6 + 0.5); + ctx.moveTo( + this._highlight_output[0] + 8, + this._highlight_output[1] + 0.5 + ); + ctx.lineTo( + this._highlight_output[0] - 4, + this._highlight_output[1] + 6 + 0.5 + ); + ctx.lineTo( + this._highlight_output[0] - 4, + this._highlight_output[1] - 6 + 0.5 + ); ctx.closePath(); } else { ctx.arc( @@ -8065,7 +8582,7 @@ LGraphNode.prototype.executeAction = function(action) } } - //the selection rectangle + //the selection rectangle if (this.dragging_rectangle) { ctx.strokeStyle = "#FFF"; ctx.strokeRect( @@ -8076,14 +8593,14 @@ LGraphNode.prototype.executeAction = function(action) ); } - //on top of link center - if(this.over_link_center && this.render_link_tooltip) - this.drawLinkTooltip( ctx, this.over_link_center ); - else - if(this.onDrawLinkTooltip) //to remove - this.onDrawLinkTooltip(ctx,null); + //on top of link center + if (this.over_link_center && this.render_link_tooltip) + this.drawLinkTooltip(ctx, this.over_link_center); + else if (this.onDrawLinkTooltip) + //to remove + this.onDrawLinkTooltip(ctx, null); - //custom info + //custom info if (this.onDrawForeground) { this.onDrawForeground(ctx, this.visible_rect); } @@ -8091,17 +8608,16 @@ LGraphNode.prototype.executeAction = function(action) ctx.restore(); } - //draws panel in the corner - if (this._graph_stack && this._graph_stack.length) { - this.drawSubgraphPanel( ctx ); - } - + //draws panel in the corner + if (this._graph_stack && this._graph_stack.length) { + this.drawSubgraphPanel(ctx); + } if (this.onDrawOverlay) { this.onDrawOverlay(ctx); } - if (area){ + if (area) { ctx.restore(); } @@ -8122,11 +8638,15 @@ LGraphNode.prototype.executeAction = function(action) console.warn("subgraph without subnode"); return; } - this.drawSubgraphPanelLeft(subgraph, subnode, ctx) - this.drawSubgraphPanelRight(subgraph, subnode, ctx) - } + this.drawSubgraphPanelLeft(subgraph, subnode, ctx); + this.drawSubgraphPanelRight(subgraph, subnode, ctx); + }; - LGraphCanvas.prototype.drawSubgraphPanelLeft = function (subgraph, subnode, ctx) { + LGraphCanvas.prototype.drawSubgraphPanelLeft = function ( + subgraph, + subnode, + ctx + ) { var num = subnode.inputs ? subnode.inputs.length : 0; var w = 200; var h = Math.floor(LiteGraph.NODE_SLOT_HEIGHT * 1.6); @@ -8154,12 +8674,12 @@ LGraphNode.prototype.executeAction = function(action) if (subnode.inputs) for (var i = 0; i < subnode.inputs.length; ++i) { var input = subnode.inputs[i]; - if (input.not_subgraph_input) - continue; + if (input.not_subgraph_input) continue; //input button clicked if (this.drawButton(20, y + 2, w - 20, h - 2)) { - var type = subnode.constructor.input_node_type || "graph/input"; + var type = + subnode.constructor.input_node_type || "graph/input"; this.graph.beforeChange(); var newnode = LiteGraph.createNode(type); if (newnode) { @@ -8174,9 +8694,7 @@ LGraphNode.prototype.executeAction = function(action) this.node_dragged.pos[0] = this.graph_mouse[0] - 5; this.node_dragged.pos[1] = this.graph_mouse[1] - 5; this.graph.afterChange(); - } - else - console.error("graph input node not found:", type); + } else console.error("graph input node not found:", type); } ctx.fillStyle = "#9C9"; ctx.beginPath(); @@ -8193,10 +8711,14 @@ LGraphNode.prototype.executeAction = function(action) if (this.drawButton(20, y + 2, w - 20, h - 2, "+", "#151515", "#222")) { this.showSubgraphPropertiesDialog(subnode); } - } - LGraphCanvas.prototype.drawSubgraphPanelRight = function (subgraph, subnode, ctx) { + }; + LGraphCanvas.prototype.drawSubgraphPanelRight = function ( + subgraph, + subnode, + ctx + ) { var num = subnode.outputs ? subnode.outputs.length : 0; - var canvas_w = this.bgcanvas.width + var canvas_w = this.bgcanvas.width; var w = 200; var h = Math.floor(LiteGraph.NODE_SLOT_HEIGHT * 1.6); @@ -8210,9 +8732,9 @@ LGraphNode.prototype.executeAction = function(action) ctx.fillStyle = "#888"; ctx.font = "14px Arial"; ctx.textAlign = "left"; - var title_text = "Graph Outputs" - var tw = ctx.measureText(title_text).width - ctx.fillText(title_text, (canvas_w - tw) - 20, 34); + var title_text = "Graph Outputs"; + var tw = ctx.measureText(title_text).width; + ctx.fillText(title_text, canvas_w - tw - 20, 34); // var pos = this.mouse; if (this.drawButton(canvas_w - w, 20, 20, 20, "X", "#151515")) { this.closeSubgraph(); @@ -8224,12 +8746,12 @@ LGraphNode.prototype.executeAction = function(action) if (subnode.outputs) for (var i = 0; i < subnode.outputs.length; ++i) { var output = subnode.outputs[i]; - if (output.not_subgraph_input) - continue; + if (output.not_subgraph_input) continue; //output button clicked if (this.drawButton(canvas_w - w, y + 2, w - 20, h - 2)) { - var type = subnode.constructor.output_node_type || "graph/output"; + var type = + subnode.constructor.output_node_type || "graph/output"; this.graph.beforeChange(); var newnode = LiteGraph.createNode(type); if (newnode) { @@ -8244,9 +8766,7 @@ LGraphNode.prototype.executeAction = function(action) this.node_dragged.pos[0] = this.graph_mouse[0] - 5; this.node_dragged.pos[1] = this.graph_mouse[1] - 5; this.graph.afterChange(); - } - else - console.error("graph input node not found:", type); + } else console.error("graph input node not found:", type); } ctx.fillStyle = "#9C9"; ctx.beginPath(); @@ -8260,69 +8780,85 @@ LGraphNode.prototype.executeAction = function(action) y += h; } //add + button - if (this.drawButton(canvas_w - w, y + 2, w - 20, h - 2, "+", "#151515", "#222")) { + if ( + this.drawButton( + canvas_w - w, + y + 2, + w - 20, + h - 2, + "+", + "#151515", + "#222" + ) + ) { this.showSubgraphPropertiesDialogRight(subnode); } - } - //Draws a button into the canvas overlay and computes if it was clicked using the immediate gui paradigm - LGraphCanvas.prototype.drawButton = function( x,y,w,h, text, bgcolor, hovercolor, textcolor ) - { - var ctx = this.ctx; - bgcolor = bgcolor || LiteGraph.NODE_DEFAULT_COLOR; - hovercolor = hovercolor || "#555"; - textcolor = textcolor || LiteGraph.NODE_TEXT_COLOR; - var pos = this.ds.convertOffsetToCanvas(this.graph_mouse); - var hover = LiteGraph.isInsideRectangle( pos[0], pos[1], x,y,w,h ); - pos = this.last_click_position ? [this.last_click_position[0], this.last_click_position[1]] : null; - if(pos) { + }; + //Draws a button into the canvas overlay and computes if it was clicked using the immediate gui paradigm + LGraphCanvas.prototype.drawButton = function ( + x, + y, + w, + h, + text, + bgcolor, + hovercolor, + textcolor + ) { + var ctx = this.ctx; + bgcolor = bgcolor || LiteGraph.NODE_DEFAULT_COLOR; + hovercolor = hovercolor || "#555"; + textcolor = textcolor || LiteGraph.NODE_TEXT_COLOR; + var pos = this.ds.convertOffsetToCanvas(this.graph_mouse); + var hover = LiteGraph.isInsideRectangle(pos[0], pos[1], x, y, w, h); + pos = this.last_click_position + ? [this.last_click_position[0], this.last_click_position[1]] + : null; + if (pos) { var rect = this.canvas.getBoundingClientRect(); pos[0] -= rect.left; pos[1] -= rect.top; } - var clicked = pos && LiteGraph.isInsideRectangle( pos[0], pos[1], x,y,w,h ); + var clicked = + pos && LiteGraph.isInsideRectangle(pos[0], pos[1], x, y, w, h); - ctx.fillStyle = hover ? hovercolor : bgcolor; - if(clicked) - ctx.fillStyle = "#AAA"; - ctx.beginPath(); - ctx.roundRect(x,y,w,h,[4] ); - ctx.fill(); + ctx.fillStyle = hover ? hovercolor : bgcolor; + if (clicked) ctx.fillStyle = "#AAA"; + ctx.beginPath(); + ctx.roundRect(x, y, w, h, [4]); + ctx.fill(); - if(text != null) - { - if(text.constructor == String) - { - ctx.fillStyle = textcolor; - ctx.textAlign = "center"; - ctx.font = ((h * 0.65)|0) + "px Arial"; - ctx.fillText( text, x + w * 0.5,y + h * 0.75 ); - ctx.textAlign = "left"; - } - } + if (text != null) { + if (text.constructor == String) { + ctx.fillStyle = textcolor; + ctx.textAlign = "center"; + ctx.font = ((h * 0.65) | 0) + "px Arial"; + ctx.fillText(text, x + w * 0.5, y + h * 0.75); + ctx.textAlign = "left"; + } + } - var was_clicked = clicked && !this.block_click; - if(clicked) - this.blockClick(); - return was_clicked; - } + var was_clicked = clicked && !this.block_click; + if (clicked) this.blockClick(); + return was_clicked; + }; - LGraphCanvas.prototype.isAreaClicked = function( x,y,w,h, hold_click ) - { - var pos = this.mouse; - var hover = LiteGraph.isInsideRectangle( pos[0], pos[1], x,y,w,h ); - pos = this.last_click_position; - var clicked = pos && LiteGraph.isInsideRectangle( pos[0], pos[1], x,y,w,h ); - var was_clicked = clicked && !this.block_click; - if(clicked && hold_click) - this.blockClick(); - return was_clicked; - } + LGraphCanvas.prototype.isAreaClicked = function (x, y, w, h, hold_click) { + var pos = this.mouse; + var hover = LiteGraph.isInsideRectangle(pos[0], pos[1], x, y, w, h); + pos = this.last_click_position; + var clicked = + pos && LiteGraph.isInsideRectangle(pos[0], pos[1], x, y, w, h); + var was_clicked = clicked && !this.block_click; + if (clicked && hold_click) this.blockClick(); + return was_clicked; + }; /** * draws some useful stats in the corner of the canvas * @method renderInfo **/ - LGraphCanvas.prototype.renderInfo = function(ctx, x, y) { + LGraphCanvas.prototype.renderInfo = function (ctx, x, y) { x = x || 10; y = y || this.canvas.height - 80; @@ -8331,11 +8867,23 @@ LGraphNode.prototype.executeAction = function(action) ctx.font = "10px Arial"; ctx.fillStyle = "#888"; - ctx.textAlign = "left"; + ctx.textAlign = "left"; 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("N: " + this.graph._nodes.length + " [" + this.visible_nodes.length + "]", 5, 13 * 3 ); + ctx.fillText( + "T: " + this.graph.globaltime.toFixed(2) + "s", + 5, + 13 * 1 + ); + ctx.fillText("I: " + this.graph.iteration, 5, 13 * 2); + ctx.fillText( + "N: " + + this.graph._nodes.length + + " [" + + this.visible_nodes.length + + "]", + 5, + 13 * 3 + ); ctx.fillText("V: " + this.graph._version, 5, 13 * 4); ctx.fillText("FPS:" + this.fps.toFixed(2), 5, 13 * 5); } else { @@ -8348,7 +8896,7 @@ LGraphNode.prototype.executeAction = function(action) * draws the back canvas (the one containing the background and the connections) * @method drawBackCanvas **/ - LGraphCanvas.prototype.drawBackCanvas = function() { + LGraphCanvas.prototype.drawBackCanvas = function () { var canvas = this.bgcanvas; if ( canvas.width != this.canvas.width || @@ -8366,14 +8914,19 @@ LGraphNode.prototype.executeAction = function(action) ctx.start(); } - var viewport = this.viewport || [0,0,ctx.canvas.width,ctx.canvas.height]; + var viewport = this.viewport || [ + 0, + 0, + ctx.canvas.width, + ctx.canvas.height, + ]; //clear if (this.clear_background) { - ctx.clearRect( viewport[0], viewport[1], viewport[2], viewport[3] ); + ctx.clearRect(viewport[0], viewport[1], viewport[2], viewport[3]); } - //show subgraph stack header + //show subgraph stack header if (this._graph_stack && this._graph_stack.length) { ctx.save(); var parent_graph = this._graph_stack[this._graph_stack.length - 1]; @@ -8404,11 +8957,10 @@ LGraphNode.prototype.executeAction = function(action) } //reset in case of error - if ( !this.viewport ) - { - ctx.restore(); - ctx.setTransform(1, 0, 0, 1, 0, 0); - } + if (!this.viewport) { + ctx.restore(); + ctx.setTransform(1, 0, 0, 1, 0, 0); + } this.visible_links.length = 0; if (this.graph) { @@ -8417,8 +8969,11 @@ LGraphNode.prototype.executeAction = function(action) this.ds.toCanvasContext(ctx); //render BG - if ( this.ds.scale < 1.5 && !bg_already_painted && this.clear_background_color ) - { + if ( + this.ds.scale < 1.5 && + !bg_already_painted && + this.clear_background_color + ) { ctx.fillStyle = this.clear_background_color; ctx.fillRect( this.visible_area[0], @@ -8439,7 +8994,7 @@ LGraphNode.prototype.executeAction = function(action) } else { ctx.globalAlpha = this.editor_alpha; } - ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled = false; // ctx.mozImageSmoothingEnabled = + ctx.imageSmoothingEnabled = ctx.imageSmoothingEnabled = false; // ctx.mozImageSmoothingEnabled = if ( !this._bg_img || this._bg_img.name != this.background_image @@ -8448,7 +9003,7 @@ LGraphNode.prototype.executeAction = function(action) this._bg_img.name = this.background_image; this._bg_img.src = this.background_image; var that = this; - this._bg_img.onload = function() { + this._bg_img.onload = function () { that.draw(true, true); }; } @@ -8536,12 +9091,18 @@ LGraphNode.prototype.executeAction = function(action) * draws the given node inside the canvas * @method drawNode **/ - LGraphCanvas.prototype.drawNode = function(node, ctx) { + LGraphCanvas.prototype.drawNode = function (node, ctx) { var glow = false; this.current_node = node; - var color = node.color || node.constructor.color || LiteGraph.NODE_DEFAULT_COLOR; - var bgcolor = node.bgcolor || node.constructor.bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR; + var color = + node.color || + node.constructor.color || + LiteGraph.NODE_DEFAULT_COLOR; + var bgcolor = + node.bgcolor || + node.constructor.bgcolor || + LiteGraph.NODE_DEFAULT_BGCOLOR; //shadow and glow if (node.mouseOver) { @@ -8661,13 +9222,16 @@ LGraphNode.prototype.executeAction = function(action) if (node.inputs) { for (var i = 0; i < node.inputs.length; i++) { var slot = node.inputs[i]; - + var slot_type = slot.type; var slot_shape = slot.shape; - + ctx.globalAlpha = editor_alpha; //change opacity of incompatible slots when dragging a connection - if ( this.connecting_output && !LiteGraph.isValidConnection( slot.type , out_slot.type) ) { + if ( + this.connecting_output && + !LiteGraph.isValidConnection(slot.type, out_slot.type) + ) { ctx.globalAlpha = 0.4 * editor_alpha; } @@ -8677,7 +9241,9 @@ LGraphNode.prototype.executeAction = function(action) this.default_connection_color_byType[slot_type] || this.default_connection_color.input_on : slot.color_off || - this.default_connection_color_byTypeOff[slot_type] || + this.default_connection_color_byTypeOff[ + slot_type + ] || this.default_connection_color_byType[slot_type] || this.default_connection_color.input_off; @@ -8690,12 +9256,12 @@ LGraphNode.prototype.executeAction = function(action) ctx.beginPath(); - if (slot_type == "array"){ + if (slot_type == "array") { slot_shape = LiteGraph.GRID_SHAPE; // place in addInput? addOutput instead? } - + var doStroke = true; - + if ( slot.type === LiteGraph.EVENT || slot.shape === LiteGraph.BOX_SHAPE @@ -8732,10 +9298,9 @@ LGraphNode.prototype.executeAction = function(action) ctx.rect(pos[0] + 2, pos[1] + 2, 2, 2); doStroke = false; } else { - if(low_quality) - ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 ); //faster - else - ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2); + if (low_quality) + ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8); //faster + else ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2); } ctx.fill(); @@ -8761,15 +9326,18 @@ LGraphNode.prototype.executeAction = function(action) if (node.outputs) { for (var i = 0; i < node.outputs.length; i++) { var slot = node.outputs[i]; - + var slot_type = slot.type; var slot_shape = slot.shape; - + //change opacity of incompatible slots when dragging a connection - if (this.connecting_input && !LiteGraph.isValidConnection( slot_type , in_slot.type) ) { + if ( + this.connecting_input && + !LiteGraph.isValidConnection(slot_type, in_slot.type) + ) { ctx.globalAlpha = 0.4 * editor_alpha; } - + var pos = node.getConnectionPos(false, i, slot_pos); pos[0] -= node.pos[0]; pos[1] -= node.pos[1]; @@ -8783,18 +9351,20 @@ LGraphNode.prototype.executeAction = function(action) this.default_connection_color_byType[slot_type] || this.default_connection_color.output_on : slot.color_off || - this.default_connection_color_byTypeOff[slot_type] || + this.default_connection_color_byTypeOff[ + slot_type + ] || this.default_connection_color_byType[slot_type] || this.default_connection_color.output_off; ctx.beginPath(); //ctx.rect( node.size[0] - 14,i*14,10,10); - if (slot_type == "array"){ + if (slot_type == "array") { slot_shape = LiteGraph.GRID_SHAPE; } - + var doStroke = true; - + if ( slot_type === LiteGraph.EVENT || slot_shape === LiteGraph.BOX_SHAPE @@ -8819,7 +9389,7 @@ LGraphNode.prototype.executeAction = function(action) ctx.lineTo(pos[0] - 4, pos[1] + 6 + 0.5); ctx.lineTo(pos[0] - 4, pos[1] - 6 + 0.5); ctx.closePath(); - } else if (slot_shape === LiteGraph.GRID_SHAPE) { + } else if (slot_shape === LiteGraph.GRID_SHAPE) { ctx.rect(pos[0] - 4, pos[1] - 4, 2, 2); ctx.rect(pos[0] - 1, pos[1] - 4, 2, 2); ctx.rect(pos[0] + 2, pos[1] - 4, 2, 2); @@ -8831,10 +9401,8 @@ LGraphNode.prototype.executeAction = function(action) ctx.rect(pos[0] + 2, pos[1] + 2, 2, 2); doStroke = false; } else { - if(low_quality) - ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8 ); - else - ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2); + if (low_quality) ctx.rect(pos[0] - 4, pos[1] - 4, 8, 8); + else ctx.arc(pos[0], pos[1], 4, 0, Math.PI * 2); } //trigger @@ -8843,8 +9411,7 @@ LGraphNode.prototype.executeAction = function(action) //if(slot.links != null && slot.links.length) ctx.fill(); - if(!low_quality && doStroke) - ctx.stroke(); + if (!low_quality && doStroke) ctx.stroke(); //render output name if (render_text) { @@ -8865,11 +9432,11 @@ LGraphNode.prototype.executeAction = function(action) ctx.globalAlpha = 1; if (node.widgets) { - var widgets_y = max_y; + var widgets_y = max_y; if (horizontal || node.widgets_up) { widgets_y = 2; } - if( node.widgets_start_y != null ) + if (node.widgets_start_y != null) widgets_y = node.widgets_start_y; this.drawNodeWidgets( node, @@ -8966,60 +9533,51 @@ LGraphNode.prototype.executeAction = function(action) ctx.globalAlpha = 1.0; }; - //used by this.over_link_center - LGraphCanvas.prototype.drawLinkTooltip = function( ctx, link ) - { - var pos = link._pos; - ctx.fillStyle = "black"; - ctx.beginPath(); - ctx.arc( pos[0], pos[1], 3, 0, Math.PI * 2 ); - ctx.fill(); - - if(link.data == null) - return; - - if(this.onDrawLinkTooltip) - if( this.onDrawLinkTooltip(ctx,link,this) == true ) - return; - - var data = link.data; - var text = null; - - if( data.constructor === Number ) - text = data.toFixed(2); - else if( data.constructor === String ) - text = "\"" + data + "\""; - else if( data.constructor === Boolean ) - text = String(data); - else if (data.toToolTip) - text = data.toToolTip(); - else - text = "[" + data.constructor.name + "]"; - - if(text == null) - return; - text = text.substr(0,30); //avoid weird - - ctx.font = "14px Courier New"; - var info = ctx.measureText(text); - var w = info.width + 20; - var h = 24; - ctx.shadowColor = "black"; - ctx.shadowOffsetX = 2; - ctx.shadowOffsetY = 2; - ctx.shadowBlur = 3; - ctx.fillStyle = "#454"; - ctx.beginPath(); - ctx.roundRect( pos[0] - w*0.5, pos[1] - 15 - h, w, h, [3]); - ctx.moveTo( pos[0] - 10, pos[1] - 15 ); - ctx.lineTo( pos[0] + 10, pos[1] - 15 ); - ctx.lineTo( pos[0], pos[1] - 5 ); - ctx.fill(); + //used by this.over_link_center + LGraphCanvas.prototype.drawLinkTooltip = function (ctx, link) { + var pos = link._pos; + ctx.fillStyle = "black"; + ctx.beginPath(); + ctx.arc(pos[0], pos[1], 3, 0, Math.PI * 2); + ctx.fill(); + + if (link.data == null) return; + + if (this.onDrawLinkTooltip) + if (this.onDrawLinkTooltip(ctx, link, this) == true) return; + + var data = link.data; + var text = null; + + if (data.constructor === Number) text = data.toFixed(2); + else if (data.constructor === String) text = '"' + data + '"'; + else if (data.constructor === Boolean) text = String(data); + else if (data.toToolTip) text = data.toToolTip(); + else text = "[" + data.constructor.name + "]"; + + if (text == null) return; + text = text.substr(0, 30); //avoid weird + + ctx.font = "14px Courier New"; + var info = ctx.measureText(text); + var w = info.width + 20; + var h = 24; + ctx.shadowColor = "black"; + ctx.shadowOffsetX = 2; + ctx.shadowOffsetY = 2; + ctx.shadowBlur = 3; + ctx.fillStyle = "#454"; + ctx.beginPath(); + ctx.roundRect(pos[0] - w * 0.5, pos[1] - 15 - h, w, h, [3]); + ctx.moveTo(pos[0] - 10, pos[1] - 15); + ctx.lineTo(pos[0] + 10, pos[1] - 15); + ctx.lineTo(pos[0], pos[1] - 5); + ctx.fill(); ctx.shadowColor = "transparent"; - ctx.textAlign = "center"; - ctx.fillStyle = "#CEC"; - ctx.fillText(text, pos[0], pos[1] - 15 - h * 0.3); - } + ctx.textAlign = "center"; + ctx.fillStyle = "#CEC"; + ctx.fillText(text, pos[0], pos[1] - 15 - h * 0.3); + }; /** * draws the shape of the given node in the canvas @@ -9027,7 +9585,7 @@ LGraphNode.prototype.executeAction = function(action) **/ var tmp_area = new Float32Array(4); - LGraphCanvas.prototype.drawNodeShape = function( + LGraphCanvas.prototype.drawNodeShape = function ( node, ctx, size, @@ -9050,7 +9608,10 @@ LGraphNode.prototype.executeAction = function(action) var title_mode = node.constructor.title_mode; var render_title = true; - if (title_mode == LiteGraph.TRANSPARENT_TITLE || title_mode == LiteGraph.NO_TITLE) { + if ( + title_mode == LiteGraph.TRANSPARENT_TITLE || + title_mode == LiteGraph.NO_TITLE + ) { render_title = false; } else if (title_mode == LiteGraph.AUTOHIDE_TITLE && mouse_over) { render_title = true; @@ -9079,7 +9640,9 @@ LGraphNode.prototype.executeAction = function(action) area[1], area[2], area[3], - shape == LiteGraph.CARD_SHAPE ? [this.round_radius,this.round_radius,0,0] : [this.round_radius] + shape == LiteGraph.CARD_SHAPE + ? [this.round_radius, this.round_radius, 0, 0] + : [this.round_radius] ); } else if (shape == LiteGraph.CIRCLE_SHAPE) { ctx.arc( @@ -9092,25 +9655,30 @@ LGraphNode.prototype.executeAction = function(action) } ctx.fill(); - //separator - if(!node.flags.collapsed && render_title) - { - ctx.shadowColor = "transparent"; - ctx.fillStyle = "rgba(0,0,0,0.2)"; - ctx.fillRect(0, -1, area[2], 2); - } + //separator + if (!node.flags.collapsed && render_title) { + ctx.shadowColor = "transparent"; + ctx.fillStyle = "rgba(0,0,0,0.2)"; + ctx.fillRect(0, -1, area[2], 2); + } } ctx.shadowColor = "transparent"; if (node.onDrawBackground) { - node.onDrawBackground(ctx, this, this.canvas, this.graph_mouse ); + node.onDrawBackground(ctx, this, this.canvas, this.graph_mouse); } //title bg (remember, it is rendered ABOVE the node) if (render_title || title_mode == LiteGraph.TRANSPARENT_TITLE) { //title bar if (node.onDrawTitleBar) { - node.onDrawTitleBar( ctx, title_height, size, this.ds.scale, fgcolor ); + node.onDrawTitleBar( + ctx, + title_height, + size, + this.ds.scale, + fgcolor + ); } else if ( title_mode != LiteGraph.TRANSPARENT_TITLE && (node.constructor.title_color || this.render_title_colored) @@ -9125,7 +9693,8 @@ LGraphNode.prototype.executeAction = function(action) if (this.use_gradients) { var grad = LGraphCanvas.gradients[title_color]; if (!grad) { - grad = LGraphCanvas.gradients[ title_color ] = ctx.createLinearGradient(0, 0, 400, 0); + grad = LGraphCanvas.gradients[title_color] = + ctx.createLinearGradient(0, 0, 400, 0); grad.addColorStop(0, title_color); // TODO refactor: validate color !! prevent DOMException grad.addColorStop(1, "#000"); } @@ -9138,13 +9707,18 @@ LGraphNode.prototype.executeAction = function(action) ctx.beginPath(); if (shape == LiteGraph.BOX_SHAPE || low_quality) { ctx.rect(0, -title_height, size[0] + 1, title_height); - } else if ( shape == LiteGraph.ROUND_SHAPE || shape == LiteGraph.CARD_SHAPE ) { + } else if ( + shape == LiteGraph.ROUND_SHAPE || + shape == LiteGraph.CARD_SHAPE + ) { ctx.roundRect( 0, -title_height, size[0] + 1, title_height, - node.flags.collapsed ? [this.round_radius] : [this.round_radius,this.round_radius,0,0] + node.flags.collapsed + ? [this.round_radius] + : [this.round_radius, this.round_radius, 0, 0] ); } ctx.fill(); @@ -9152,15 +9726,19 @@ LGraphNode.prototype.executeAction = function(action) } var colState = false; - if (LiteGraph.node_box_coloured_by_mode){ - if(LiteGraph.NODE_MODES_COLORS[node.mode]){ + if (LiteGraph.node_box_coloured_by_mode) { + if (LiteGraph.NODE_MODES_COLORS[node.mode]) { colState = LiteGraph.NODE_MODES_COLORS[node.mode]; } } - if (LiteGraph.node_box_coloured_when_on){ - colState = node.action_triggered ? "#FFF" : (node.execute_triggered ? "#AAA" : colState); + if (LiteGraph.node_box_coloured_when_on) { + colState = node.action_triggered + ? "#FFF" + : node.execute_triggered + ? "#AAA" + : colState; } - + //title box var box_size = 10; if (node.onDrawTitleBox) { @@ -9182,22 +9760,29 @@ LGraphNode.prototype.executeAction = function(action) ); ctx.fill(); } - - ctx.fillStyle = node.boxcolor || colState || LiteGraph.NODE_DEFAULT_BOXCOLOR; - if(low_quality) - ctx.fillRect( title_height * 0.5 - box_size *0.5, title_height * -0.5 - box_size *0.5, box_size , box_size ); - else - { - ctx.beginPath(); - ctx.arc( - title_height * 0.5, - title_height * -0.5, - box_size * 0.5, - 0, - Math.PI * 2 - ); - ctx.fill(); - } + + ctx.fillStyle = + node.boxcolor || + colState || + LiteGraph.NODE_DEFAULT_BOXCOLOR; + if (low_quality) + ctx.fillRect( + title_height * 0.5 - box_size * 0.5, + title_height * -0.5 - box_size * 0.5, + box_size, + box_size + ); + else { + ctx.beginPath(); + ctx.arc( + title_height * 0.5, + title_height * -0.5, + box_size * 0.5, + 0, + Math.PI * 2 + ); + ctx.fill(); + } } else { if (low_quality) { ctx.fillStyle = "black"; @@ -9208,7 +9793,10 @@ LGraphNode.prototype.executeAction = function(action) box_size + 2 ); } - ctx.fillStyle = node.boxcolor || colState || LiteGraph.NODE_DEFAULT_BOXCOLOR; + ctx.fillStyle = + node.boxcolor || + colState || + LiteGraph.NODE_DEFAULT_BOXCOLOR; ctx.fillRect( (title_height - box_size) * 0.5, (title_height + box_size) * -0.5, @@ -9244,8 +9832,8 @@ LGraphNode.prototype.executeAction = function(action) ctx.textAlign = "left"; var measure = ctx.measureText(title); ctx.fillText( - title.substr(0,20), //avoid urls too long - title_height,// + measure.width * 0.5, + title.substr(0, 20), //avoid urls too long + title_height, // + measure.width * 0.5, LiteGraph.NODE_TITLE_TEXT_Y - title_height ); ctx.textAlign = "left"; @@ -9260,29 +9848,39 @@ LGraphNode.prototype.executeAction = function(action) } } - //subgraph box - if (!node.flags.collapsed && node.subgraph && !node.skip_subgraph_button) { - var w = LiteGraph.NODE_TITLE_HEIGHT; - var x = node.size[0] - w; - var over = LiteGraph.isInsideRectangle( this.graph_mouse[0] - node.pos[0], this.graph_mouse[1] - node.pos[1], x+2, -w+2, w-4, w-4 ); - ctx.fillStyle = over ? "#888" : "#555"; - if( shape == LiteGraph.BOX_SHAPE || low_quality) - ctx.fillRect(x+2, -w+2, w-4, w-4); - else - { - ctx.beginPath(); - ctx.roundRect(x+2, -w+2, w-4, w-4,[4]); - ctx.fill(); - } - ctx.fillStyle = "#333"; - ctx.beginPath(); - ctx.moveTo(x + w * 0.2, -w * 0.6); - ctx.lineTo(x + w * 0.8, -w * 0.6); - ctx.lineTo(x + w * 0.5, -w * 0.3); - ctx.fill(); - } + //subgraph box + if ( + !node.flags.collapsed && + node.subgraph && + !node.skip_subgraph_button + ) { + var w = LiteGraph.NODE_TITLE_HEIGHT; + var x = node.size[0] - w; + var over = LiteGraph.isInsideRectangle( + this.graph_mouse[0] - node.pos[0], + this.graph_mouse[1] - node.pos[1], + x + 2, + -w + 2, + w - 4, + w - 4 + ); + ctx.fillStyle = over ? "#888" : "#555"; + if (shape == LiteGraph.BOX_SHAPE || low_quality) + ctx.fillRect(x + 2, -w + 2, w - 4, w - 4); + else { + ctx.beginPath(); + ctx.roundRect(x + 2, -w + 2, w - 4, w - 4, [4]); + ctx.fill(); + } + ctx.fillStyle = "#333"; + ctx.beginPath(); + ctx.moveTo(x + w * 0.2, -w * 0.6); + ctx.lineTo(x + w * 0.8, -w * 0.6); + ctx.lineTo(x + w * 0.5, -w * 0.3); + ctx.fill(); + } - //custom title render + //custom title render if (node.onDrawTitle) { node.onDrawTitle(ctx); } @@ -9325,7 +9923,7 @@ LGraphNode.prototype.executeAction = function(action) -6 + area[1], 12 + area[2], 12 + area[3], - [this.round_radius * 2,2,this.round_radius * 2,2] + [this.round_radius * 2, 2, this.round_radius * 2, 2] ); } else if (shape == LiteGraph.CIRCLE_SHAPE) { ctx.arc( @@ -9341,10 +9939,10 @@ LGraphNode.prototype.executeAction = function(action) ctx.strokeStyle = fgcolor; ctx.globalAlpha = 1; } - + // these counter helps in conditioning drawing based on if the node has been executed or an action occurred - if (node.execute_triggered>0) node.execute_triggered--; - if (node.action_triggered>0) node.action_triggered--; + if (node.execute_triggered > 0) node.execute_triggered--; + if (node.action_triggered > 0) node.action_triggered--; }; var margin_area = new Float32Array(4); @@ -9357,7 +9955,7 @@ LGraphNode.prototype.executeAction = function(action) * OPTIMIZE THIS: pre-catch connections position instead of recomputing them every time * @method drawConnections **/ - LGraphCanvas.prototype.drawConnections = function(ctx) { + LGraphCanvas.prototype.drawConnections = function (ctx) { var now = LiteGraph.getTime(); var visible_area = this.visible_area; margin_area[0] = visible_area[0] - 20; @@ -9401,7 +9999,7 @@ LGraphNode.prototype.executeAction = function(action) if (start_node_slot == -1) { start_node_slotpos = [ start_node.pos[0] + 10, - start_node.pos[1] + 10 + start_node.pos[1] + 10, ]; } else { start_node_slotpos = start_node.getConnectionPos( @@ -9491,7 +10089,7 @@ LGraphNode.prototype.executeAction = function(action) * @param {number} end_dir the direction enum * @param {number} num_sublines number of sublines (useful to represent vec3 or rgb) **/ - LGraphCanvas.prototype.renderLink = function( + LGraphCanvas.prototype.renderLink = function ( ctx, a, b, @@ -9765,7 +10363,7 @@ LGraphNode.prototype.executeAction = function(action) }; //returns the link center point based on curvature - LGraphCanvas.prototype.computeConnectionPoint = function( + LGraphCanvas.prototype.computeConnectionPoint = function ( a, b, t, @@ -9820,7 +10418,7 @@ LGraphNode.prototype.executeAction = function(action) return [x, y]; }; - LGraphCanvas.prototype.drawExecutionOrder = function(ctx) { + LGraphCanvas.prototype.drawExecutionOrder = function (ctx) { ctx.shadowColor = "transparent"; ctx.globalAlpha = 0.25; @@ -9860,7 +10458,7 @@ LGraphNode.prototype.executeAction = function(action) * draws the widgets stored inside a node * @method drawNodeWidgets **/ - LGraphCanvas.prototype.drawNodeWidgets = function( + LGraphCanvas.prototype.drawNodeWidgets = function ( node, posY, ctx, @@ -9879,7 +10477,7 @@ LGraphNode.prototype.executeAction = function(action) var outline_color = LiteGraph.WIDGET_OUTLINE_COLOR; var background_color = LiteGraph.WIDGET_BGCOLOR; var text_color = LiteGraph.WIDGET_TEXT_COLOR; - var secondary_text_color = LiteGraph.WIDGET_SECONDARY_TEXT_COLOR; + var secondary_text_color = LiteGraph.WIDGET_SECONDARY_TEXT_COLOR; var margin = 15; for (var i = 0; i < widgets.length; ++i) { @@ -9892,10 +10490,9 @@ LGraphNode.prototype.executeAction = function(action) ctx.strokeStyle = outline_color; ctx.fillStyle = "#222"; ctx.textAlign = "left"; - //ctx.lineWidth = 2; - if(w.disabled) - ctx.globalAlpha *= 0.5; - var widget_width = w.width || width; + //ctx.lineWidth = 2; + if (w.disabled) ctx.globalAlpha *= 0.5; + var widget_width = w.width || width; switch (w.type) { case "button": @@ -9905,12 +10502,16 @@ LGraphNode.prototype.executeAction = function(action) this.dirty_canvas = true; } ctx.fillRect(margin, y, widget_width - margin * 2, H); - if(show_text && !w.disabled) - ctx.strokeRect( margin, y, widget_width - margin * 2, H ); + if (show_text && !w.disabled) + ctx.strokeRect(margin, y, widget_width - margin * 2, H); if (show_text) { ctx.textAlign = "center"; ctx.fillStyle = text_color; - ctx.fillText(w.label || w.name, widget_width * 0.5, y + H * 0.7); + ctx.fillText( + w.label || w.name, + widget_width * 0.5, + y + H * 0.7 + ); } break; case "toggle": @@ -9919,23 +10520,31 @@ LGraphNode.prototype.executeAction = function(action) ctx.fillStyle = background_color; ctx.beginPath(); if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]); - else - ctx.rect(margin, y, widget_width - margin * 2, H ); + ctx.roundRect(margin, y, widget_width - margin * 2, H, [ + H * 0.5, + ]); + else ctx.rect(margin, y, widget_width - margin * 2, H); ctx.fill(); - if(show_text && !w.disabled) - ctx.stroke(); + if (show_text && !w.disabled) ctx.stroke(); ctx.fillStyle = w.value ? "#89A" : "#333"; ctx.beginPath(); - ctx.arc( widget_width - margin * 2, y + H * 0.5, H * 0.36, 0, Math.PI * 2 ); + ctx.arc( + widget_width - margin * 2, + y + H * 0.5, + H * 0.36, + 0, + Math.PI * 2 + ); ctx.fill(); if (show_text) { ctx.fillStyle = secondary_text_color; - const label = w.label || w.name; + const label = w.label || w.name; if (label != null) { ctx.fillText(label, margin * 2, y + H * 0.7); } - ctx.fillStyle = w.value ? text_color : secondary_text_color; + ctx.fillStyle = w.value + ? text_color + : secondary_text_color; ctx.textAlign = "right"; ctx.fillText( w.value @@ -9951,28 +10560,48 @@ LGraphNode.prototype.executeAction = function(action) ctx.fillRect(margin, y, widget_width - margin * 2, H); var range = w.options.max - w.options.min; var nvalue = (w.value - w.options.min) / range; - if(nvalue < 0.0) nvalue = 0.0; - if(nvalue > 1.0) nvalue = 1.0; - ctx.fillStyle = w.options.hasOwnProperty("slider_color") ? w.options.slider_color : (active_widget == w ? "#89A" : "#678"); - ctx.fillRect(margin, y, nvalue * (widget_width - margin * 2), H); - if(show_text && !w.disabled) - ctx.strokeRect(margin, y, widget_width - margin * 2, H); + if (nvalue < 0.0) nvalue = 0.0; + if (nvalue > 1.0) nvalue = 1.0; + ctx.fillStyle = w.options.hasOwnProperty("slider_color") + ? w.options.slider_color + : active_widget == w + ? "#89A" + : "#678"; + ctx.fillRect( + margin, + y, + nvalue * (widget_width - margin * 2), + H + ); + if (show_text && !w.disabled) + ctx.strokeRect(margin, y, widget_width - margin * 2, H); if (w.marker) { var marker_nvalue = (w.marker - w.options.min) / range; - if(marker_nvalue < 0.0) marker_nvalue = 0.0; - if(marker_nvalue > 1.0) marker_nvalue = 1.0; - ctx.fillStyle = w.options.hasOwnProperty("marker_color") ? w.options.marker_color : "#AA9"; - ctx.fillRect( margin + marker_nvalue * (widget_width - margin * 2), y, 2, H ); + if (marker_nvalue < 0.0) marker_nvalue = 0.0; + if (marker_nvalue > 1.0) marker_nvalue = 1.0; + ctx.fillStyle = w.options.hasOwnProperty("marker_color") + ? w.options.marker_color + : "#AA9"; + ctx.fillRect( + margin + + marker_nvalue * (widget_width - margin * 2), + y, + 2, + H + ); } if (show_text) { ctx.textAlign = "center"; ctx.fillStyle = text_color; ctx.fillText( - w.label || w.name + " " + Number(w.value).toFixed( - w.options.precision != null - ? w.options.precision - : 3 - ), + w.label || + w.name + + " " + + Number(w.value).toFixed( + w.options.precision != null + ? w.options.precision + : 3 + ), widget_width * 0.5, y + H * 0.7 ); @@ -9984,30 +10613,33 @@ LGraphNode.prototype.executeAction = function(action) ctx.strokeStyle = outline_color; ctx.fillStyle = background_color; ctx.beginPath(); - if(show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5] ); - else - ctx.rect(margin, y, widget_width - margin * 2, H ); + if (show_text) + ctx.roundRect(margin, y, widget_width - margin * 2, H, [ + H * 0.5, + ]); + else ctx.rect(margin, y, widget_width - margin * 2, H); ctx.fill(); if (show_text) { - if(!w.disabled) - ctx.stroke(); + if (!w.disabled) ctx.stroke(); ctx.fillStyle = text_color; - if(!w.disabled) - { - ctx.beginPath(); - ctx.moveTo(margin + 16, y + 5); - ctx.lineTo(margin + 6, y + H * 0.5); - ctx.lineTo(margin + 16, y + H - 5); - ctx.fill(); - ctx.beginPath(); - ctx.moveTo(widget_width - margin - 16, y + 5); - ctx.lineTo(widget_width - margin - 6, y + H * 0.5); - ctx.lineTo(widget_width - margin - 16, y + H - 5); - ctx.fill(); - } + if (!w.disabled) { + ctx.beginPath(); + ctx.moveTo(margin + 16, y + 5); + ctx.lineTo(margin + 6, y + H * 0.5); + ctx.lineTo(margin + 16, y + H - 5); + ctx.fill(); + ctx.beginPath(); + ctx.moveTo(widget_width - margin - 16, y + 5); + ctx.lineTo(widget_width - margin - 6, y + H * 0.5); + ctx.lineTo(widget_width - margin - 16, y + H - 5); + ctx.fill(); + } ctx.fillStyle = secondary_text_color; - ctx.fillText(w.label || w.name, margin * 2 + 5, y + H * 0.7); + ctx.fillText( + w.label || w.name, + margin * 2 + 5, + y + H * 0.7 + ); ctx.fillStyle = text_color; ctx.textAlign = "right"; if (w.type == "number") { @@ -10021,15 +10653,14 @@ LGraphNode.prototype.executeAction = function(action) y + H * 0.7 ); } else { - var v = w.value; - if( w.options.values ) - { - var values = w.options.values; - if( values.constructor === Function ) - values = values(); - if(values && values.constructor !== Array) - v = values[ w.value ]; - } + var v = w.value; + if (w.options.values) { + var values = w.options.values; + if (values.constructor === Function) + values = values(); + if (values && values.constructor !== Array) + v = values[w.value]; + } ctx.fillText( v, widget_width - margin * 2 - 20, @@ -10045,28 +10676,32 @@ LGraphNode.prototype.executeAction = function(action) ctx.fillStyle = background_color; ctx.beginPath(); if (show_text) - ctx.roundRect(margin, y, widget_width - margin * 2, H, [H * 0.5]); - else - ctx.rect( margin, y, widget_width - margin * 2, H ); + ctx.roundRect(margin, y, widget_width - margin * 2, H, [ + H * 0.5, + ]); + else ctx.rect(margin, y, widget_width - margin * 2, H); ctx.fill(); - if (show_text) { - if(!w.disabled) - ctx.stroke(); - ctx.save(); - ctx.beginPath(); - ctx.rect(margin, y, widget_width - margin * 2, H); - ctx.clip(); - - //ctx.stroke(); + if (show_text) { + if (!w.disabled) ctx.stroke(); + ctx.save(); + ctx.beginPath(); + ctx.rect(margin, y, widget_width - margin * 2, H); + ctx.clip(); + + //ctx.stroke(); ctx.fillStyle = secondary_text_color; - const label = w.label || w.name; + const label = w.label || w.name; if (label != null) { ctx.fillText(label, margin * 2, y + H * 0.7); } ctx.fillStyle = text_color; ctx.textAlign = "right"; - ctx.fillText(String(w.value).substr(0,30), widget_width - margin * 2, y + H * 0.7); //30 chars max - ctx.restore(); + ctx.fillText( + String(w.value).substr(0, 30), + widget_width - margin * 2, + y + H * 0.7 + ); //30 chars max + ctx.restore(); } break; default: @@ -10076,24 +10711,27 @@ LGraphNode.prototype.executeAction = function(action) break; } posY += (w.computeSize ? w.computeSize(widget_width)[1] : H) + 4; - ctx.globalAlpha = this.editor_alpha; - + ctx.globalAlpha = this.editor_alpha; } ctx.restore(); - ctx.textAlign = "left"; + ctx.textAlign = "left"; }; /** * process an event on widgets * @method processNodeWidgets **/ - LGraphCanvas.prototype.processNodeWidgets = function( + LGraphCanvas.prototype.processNodeWidgets = function ( node, pos, event, active_widget ) { - if (!node.widgets || !node.widgets.length || (!this.allow_interaction && !node.flags.allow_interaction)) { + if ( + !node.widgets || + !node.widgets.length || + (!this.allow_interaction && !node.flags.allow_interaction) + ) { return null; } @@ -10106,179 +10744,229 @@ LGraphNode.prototype.executeAction = function(action) for (var i = 0; i < node.widgets.length; ++i) { var w = node.widgets[i]; - if(!w || w.disabled) - continue; - var widget_height = w.computeSize ? w.computeSize(width)[1] : LiteGraph.NODE_WIDGET_HEIGHT; - var widget_width = w.width || width; - //outside - if ( w != active_widget && - (x < 6 || x > widget_width - 12 || y < w.last_y || y > w.last_y + widget_height || w.last_y === undefined) ) - continue; + if (!w || w.disabled) continue; + var widget_height = w.computeSize + ? w.computeSize(width)[1] + : LiteGraph.NODE_WIDGET_HEIGHT; + var widget_width = w.width || width; + //outside + if ( + w != active_widget && + (x < 6 || + x > widget_width - 12 || + y < w.last_y || + y > w.last_y + widget_height || + w.last_y === undefined) + ) + continue; - var old_value = w.value; + var old_value = w.value; //if ( w == active_widget || (x > 6 && x < widget_width - 12 && y > w.last_y && y < w.last_y + widget_height) ) { - //inside widget - switch (w.type) { - case "button": - if (event.type === LiteGraph.pointerevents_method+"down") { + //inside widget + switch (w.type) { + case "button": + if ( + event.type === + LiteGraph.pointerevents_method + "down" + ) { if (w.callback) { - setTimeout(function() { + setTimeout(function () { w.callback(w, that, node, pos, event); }, 20); } w.clicked = true; this.dirty_canvas = true; } - break; - case "slider": - var old_value = w.value; - var nvalue = clamp((x - 15) / (widget_width - 30), 0, 1); - if(w.options.read_only) break; - w.value = w.options.min + (w.options.max - w.options.min) * nvalue; - if (old_value != w.value) { - setTimeout(function() { - inner_value_change(w, w.value); - }, 20); - } - this.dirty_canvas = true; - break; - case "number": - case "combo": - var old_value = w.value; - if (event.type == LiteGraph.pointerevents_method+"move" && w.type == "number") { - if(deltaX) - w.value += deltaX * 0.1 * (w.options.step || 1); - if ( w.options.min != null && w.value < w.options.min ) { - w.value = w.options.min; - } - if ( w.options.max != null && w.value > w.options.max ) { - w.value = w.options.max; - } - } else if (event.type == LiteGraph.pointerevents_method+"down") { - var values = w.options.values; - if (values && values.constructor === Function) { - values = w.options.values(w, node); - } - var values_list = null; - - if( w.type != "number") - values_list = values.constructor === Array ? values : Object.keys(values); - - var delta = x < 40 ? -1 : x > widget_width - 40 ? 1 : 0; - if (w.type == "number") { - w.value += delta * 0.1 * (w.options.step || 1); - if ( w.options.min != null && w.value < w.options.min ) { - w.value = w.options.min; - } - if ( w.options.max != null && w.value > w.options.max ) { - w.value = w.options.max; - } - } else if (delta) { //clicked in arrow, used for combos - var index = -1; - this.last_mouseclick = 0; //avoids dobl click event - if(values.constructor === Object) - index = values_list.indexOf( String( w.value ) ) + delta; - else - index = values_list.indexOf( w.value ) + delta; - if (index >= values_list.length) { - index = values_list.length - 1; - } - if (index < 0) { - index = 0; - } - if( values.constructor === Array ) - w.value = values[index]; - else - w.value = index; - } else { //combo clicked - var text_values = values != values_list ? Object.values(values) : values; - var menu = new LiteGraph.ContextMenu(text_values, { - scale: Math.max(1, this.ds.scale), - event: event, - className: "dark", - callback: inner_clicked.bind(w) - }, - ref_window); - function inner_clicked(v, option, event) { - if(values != values_list) - v = text_values.indexOf(v); - this.value = v; - inner_value_change(this, v); - that.dirty_canvas = true; - return false; - } - } - } //end mousedown - else if(event.type == LiteGraph.pointerevents_method+"up" && w.type == "number") - { - var delta = x < 40 ? -1 : x > widget_width - 40 ? 1 : 0; - if (event.click_time < 200 && delta == 0) { - this.prompt("Value",w.value,function(v) { - // check if v is a valid equation or a number - if (/^[0-9+\-*/()\s]+|\d+\.\d+$/.test(v)) { - try {//solve the equation if possible - v = eval(v); - } catch (e) { } - } - this.value = Number(v); - inner_value_change(this, this.value); - }.bind(w), - event); - } - } - - if( old_value != w.value ) - setTimeout( - function() { - inner_value_change(this, this.value); - }.bind(w), - 20 - ); - this.dirty_canvas = true; - break; - case "toggle": - if (event.type == LiteGraph.pointerevents_method+"down") { - w.value = !w.value; - setTimeout(function() { - inner_value_change(w, w.value); - }, 20); - } - break; - case "string": - case "text": - if (event.type == LiteGraph.pointerevents_method+"down") { - this.prompt("Value",w.value,function(v) { - inner_value_change(this, v); - }.bind(w), - event,w.options ? w.options.multiline : false ); - } - break; - default: - if (w.mouse) { - this.dirty_canvas = w.mouse(event, [x, y], node); - } - break; - } //end switch - - //value changed - if( old_value != w.value ) - { - if(node.onWidgetChanged) - node.onWidgetChanged( w.name,w.value,old_value,w ); + break; + case "slider": + var old_value = w.value; + var nvalue = clamp((x - 15) / (widget_width - 30), 0, 1); + if (w.options.read_only) break; + w.value = + w.options.min + + (w.options.max - w.options.min) * nvalue; + if (old_value != w.value) { + setTimeout(function () { + inner_value_change(w, w.value); + }, 20); + } + this.dirty_canvas = true; + break; + case "number": + case "combo": + var old_value = w.value; + if ( + event.type == LiteGraph.pointerevents_method + "move" && + w.type == "number" + ) { + if (deltaX) + w.value += deltaX * 0.1 * (w.options.step || 1); + if (w.options.min != null && w.value < w.options.min) { + w.value = w.options.min; + } + if (w.options.max != null && w.value > w.options.max) { + w.value = w.options.max; + } + } else if ( + event.type == + LiteGraph.pointerevents_method + "down" + ) { + var values = w.options.values; + if (values && values.constructor === Function) { + values = w.options.values(w, node); + } + var values_list = null; + + if (w.type != "number") + values_list = + values.constructor === Array + ? values + : Object.keys(values); + + var delta = x < 40 ? -1 : x > widget_width - 40 ? 1 : 0; + if (w.type == "number") { + w.value += delta * 0.1 * (w.options.step || 1); + if ( + w.options.min != null && + w.value < w.options.min + ) { + w.value = w.options.min; + } + if ( + w.options.max != null && + w.value > w.options.max + ) { + w.value = w.options.max; + } + } else if (delta) { + //clicked in arrow, used for combos + var index = -1; + this.last_mouseclick = 0; //avoids dobl click event + if (values.constructor === Object) + index = + values_list.indexOf(String(w.value)) + + delta; + else index = values_list.indexOf(w.value) + delta; + if (index >= values_list.length) { + index = values_list.length - 1; + } + if (index < 0) { + index = 0; + } + if (values.constructor === Array) + w.value = values[index]; + else w.value = index; + } else { + //combo clicked + var text_values = + values != values_list + ? Object.values(values) + : values; + var menu = new LiteGraph.ContextMenu( + text_values, + { + scale: Math.max(1, this.ds.scale), + event: event, + className: "dark", + callback: inner_clicked.bind(w), + }, + ref_window + ); + function inner_clicked(v, option, event) { + if (values != values_list) + v = text_values.indexOf(v); + this.value = v; + inner_value_change(this, v); + that.dirty_canvas = true; + return false; + } + } + } //end mousedown + else if ( + event.type == LiteGraph.pointerevents_method + "up" && + w.type == "number" + ) { + var delta = x < 40 ? -1 : x > widget_width - 40 ? 1 : 0; + if (event.click_time < 200 && delta == 0) { + this.prompt( + "Value", + w.value, + function (v) { + // check if v is a valid equation or a number + if (/^[0-9+\-*/()\s]+|\d+\.\d+$/.test(v)) { + try { + //solve the equation if possible + v = eval(v); + } catch (e) {} + } + this.value = Number(v); + inner_value_change(this, this.value); + }.bind(w), + event + ); + } + } + + if (old_value != w.value) + setTimeout( + function () { + inner_value_change(this, this.value); + }.bind(w), + 20 + ); + this.dirty_canvas = true; + break; + case "toggle": + if (event.type == LiteGraph.pointerevents_method + "down") { + w.value = !w.value; + setTimeout(function () { + inner_value_change(w, w.value); + }, 20); + } + break; + case "string": + case "text": + if (event.type == LiteGraph.pointerevents_method + "down") { + this.prompt( + "Value", + w.value, + function (v) { + inner_value_change(this, v); + }.bind(w), + event, + w.options ? w.options.multiline : false + ); + } + break; + default: + if (w.mouse) { + this.dirty_canvas = w.mouse(event, [x, y], node); + } + break; + } //end switch + + //value changed + if (old_value != w.value) { + if (node.onWidgetChanged) + node.onWidgetChanged(w.name, w.value, old_value, w); node.graph._version++; - } + } - return w; - }//end for + return w; + } //end for function inner_value_change(widget, value) { - if(widget.type == "number"){ + if (widget.type == "number") { value = Number(value); } widget.value = value; - if ( widget.options && widget.options.property && node.properties[widget.options.property] !== undefined ) { - node.setProperty( widget.options.property, value ); + if ( + widget.options && + widget.options.property && + node.properties[widget.options.property] !== undefined + ) { + node.setProperty(widget.options.property, value); } if (widget.callback) { widget.callback(widget.value, that, node, pos, event); @@ -10292,7 +10980,7 @@ LGraphNode.prototype.executeAction = function(action) * draws every group area in the background * @method drawGroups **/ - LGraphCanvas.prototype.drawGroups = function(canvas, ctx) { + LGraphCanvas.prototype.drawGroups = function (canvas, ctx) { if (!this.graph) { return; } @@ -10329,14 +11017,14 @@ LGraphNode.prototype.executeAction = function(action) var font_size = group.font_size || LiteGraph.DEFAULT_GROUP_FONT_SIZE; ctx.font = font_size + "px Arial"; - ctx.textAlign = "left"; + ctx.textAlign = "left"; ctx.fillText(group.title, pos[0] + 4, pos[1] + font_size); } ctx.restore(); }; - LGraphCanvas.prototype.adjustNodesSize = function() { + LGraphCanvas.prototype.adjustNodesSize = function () { var nodes = this.graph._nodes; for (var i = 0; i < nodes.length; ++i) { nodes[i].size = nodes[i].computeSize(); @@ -10348,7 +11036,7 @@ LGraphNode.prototype.executeAction = function(action) * resizes the canvas to a given size, if no size is passed, then it tries to fill the parentNode * @method resize **/ - LGraphCanvas.prototype.resize = function(width, height) { + LGraphCanvas.prototype.resize = function (width, height) { if (!width && !height) { var parent = this.canvas.parentNode; width = parent.offsetWidth; @@ -10371,7 +11059,7 @@ LGraphNode.prototype.executeAction = function(action) * this feature was designed when graphs where meant to create user interfaces * @method switchLiveMode **/ - LGraphCanvas.prototype.switchLiveMode = function(transition) { + LGraphCanvas.prototype.switchLiveMode = function (transition) { if (!transition) { this.live_mode = !this.live_mode; this.dirty_canvas = true; @@ -10386,7 +11074,7 @@ LGraphNode.prototype.executeAction = function(action) this.editor_alpha = 0.1; } - var t = setInterval(function() { + var t = setInterval(function () { self.editor_alpha *= delta; self.dirty_canvas = true; self.dirty_bgcanvas = true; @@ -10404,7 +11092,7 @@ LGraphNode.prototype.executeAction = function(action) }, 1); }; - LGraphCanvas.prototype.onNodeSelectionChange = function(node) { + LGraphCanvas.prototype.onNodeSelectionChange = function (node) { return; //disabled }; @@ -10467,7 +11155,7 @@ LGraphNode.prototype.executeAction = function(action) /* CONTEXT MENU ********************/ - LGraphCanvas.onGroupAdd = function(info, entry, mouse_event) { + LGraphCanvas.onGroupAdd = function (info, entry, mouse_event) { var canvas = LGraphCanvas.active_canvas; var ref_window = canvas.getCanvasWindow(); @@ -10481,7 +11169,7 @@ LGraphNode.prototype.executeAction = function(action) * @param nodes {LGraphNode[]} the nodes to from which boundary nodes will be extracted * @return {{left: LGraphNode, top: LGraphNode, right: LGraphNode, bottom: LGraphNode}} */ - LGraphCanvas.getBoundaryNodes = function(nodes) { + LGraphCanvas.getBoundaryNodes = function (nodes) { let top = null; let right = null; let bottom = null; @@ -10497,7 +11185,10 @@ LGraphNode.prototype.executeAction = function(action) if (right === null || x + width > right.pos[0] + right.size[0]) { right = node; } - if (bottom === null || y + height > bottom.pos[1] + bottom.size[1]) { + if ( + bottom === null || + y + height > bottom.pos[1] + bottom.size[1] + ) { bottom = node; } if (left === null || x < left.pos[0]) { @@ -10506,19 +11197,21 @@ LGraphNode.prototype.executeAction = function(action) } return { - "top": top, - "right": right, - "bottom": bottom, - "left": left + top: top, + right: right, + bottom: bottom, + left: left, }; - } + }; /** * Determines the furthest nodes in each direction for the currently selected nodes * @return {{left: LGraphNode, top: LGraphNode, right: LGraphNode, bottom: LGraphNode}} */ - LGraphCanvas.prototype.boundaryNodesForSelection = function() { - return LGraphCanvas.getBoundaryNodes(Object.values(this.selected_nodes)); - } + LGraphCanvas.prototype.boundaryNodesForSelection = function () { + return LGraphCanvas.getBoundaryNodes( + Object.values(this.selected_nodes) + ); + }; /** * @@ -10532,22 +11225,25 @@ LGraphNode.prototype.executeAction = function(action) } const canvas = LGraphCanvas.active_canvas; - let boundaryNodes = [] + let boundaryNodes = []; if (align_to === undefined) { - boundaryNodes = LGraphCanvas.getBoundaryNodes(nodes) + boundaryNodes = LGraphCanvas.getBoundaryNodes(nodes); } else { boundaryNodes = { - "top": align_to, - "right": align_to, - "bottom": align_to, - "left": align_to - } + top: align_to, + right: align_to, + bottom: align_to, + left: align_to, + }; } for (const [_, node] of Object.entries(canvas.selected_nodes)) { switch (direction) { case "right": - node.pos[0] = boundaryNodes["right"].pos[0] + boundaryNodes["right"].size[0] - node.size[0]; + node.pos[0] = + boundaryNodes["right"].pos[0] + + boundaryNodes["right"].size[0] - + node.size[0]; break; case "left": node.pos[0] = boundaryNodes["left"].pos[0]; @@ -10556,7 +11252,10 @@ LGraphNode.prototype.executeAction = function(action) node.pos[1] = boundaryNodes["top"].pos[1]; break; case "bottom": - node.pos[1] = boundaryNodes["bottom"].pos[1] + boundaryNodes["bottom"].size[1] - node.size[1]; + node.pos[1] = + boundaryNodes["bottom"].pos[1] + + boundaryNodes["bottom"].size[1] - + node.size[1]; break; } } @@ -10565,7 +11264,13 @@ LGraphNode.prototype.executeAction = function(action) canvas.dirty_bgcanvas = true; }; - LGraphCanvas.onNodeAlign = function(value, options, event, prev_menu, node) { + LGraphCanvas.onNodeAlign = function ( + value, + options, + event, + prev_menu, + node + ) { new LiteGraph.ContextMenu(["Top", "Bottom", "Left", "Right"], { event: event, callback: inner_clicked, @@ -10573,11 +11278,15 @@ LGraphNode.prototype.executeAction = function(action) }); function inner_clicked(value) { - LGraphCanvas.alignNodes(LGraphCanvas.active_canvas.selected_nodes, value.toLowerCase(), node); + LGraphCanvas.alignNodes( + LGraphCanvas.active_canvas.selected_nodes, + value.toLowerCase(), + node + ); } - } + }; - LGraphCanvas.onGroupAlign = function(value, options, event, prev_menu) { + LGraphCanvas.onGroupAlign = function (value, options, event, prev_menu) { new LiteGraph.ContextMenu(["Top", "Bottom", "Left", "Right"], { event: event, callback: inner_clicked, @@ -10585,85 +11294,110 @@ LGraphNode.prototype.executeAction = function(action) }); function inner_clicked(value) { - LGraphCanvas.alignNodes(LGraphCanvas.active_canvas.selected_nodes, value.toLowerCase()); + LGraphCanvas.alignNodes( + LGraphCanvas.active_canvas.selected_nodes, + value.toLowerCase() + ); } - } + }; LGraphCanvas.onMenuAdd = function (node, options, e, prev_menu, callback) { - var canvas = LGraphCanvas.active_canvas; var ref_window = canvas.getCanvasWindow(); var graph = canvas.graph; - if (!graph) - return; + if (!graph) return; - function inner_onMenuAdded(base_category ,prev_menu){ - - var categories = LiteGraph.getNodeTypesCategories(canvas.filter || graph.filter).filter(function(category){return category.startsWith(base_category)}); + function inner_onMenuAdded(base_category, prev_menu) { + var categories = LiteGraph.getNodeTypesCategories( + canvas.filter || graph.filter + ).filter(function (category) { + return category.startsWith(base_category); + }); var entries = []; - - categories.map(function(category){ - - if (!category) - return; - - var base_category_regex = new RegExp('^(' + base_category + ')'); - var category_name = category.replace(base_category_regex,"").split('/')[0]; - var category_path = base_category === '' ? category_name + '/' : base_category + category_name + '/'; - + + categories.map(function (category) { + if (!category) return; + + var base_category_regex = new RegExp( + "^(" + base_category + ")" + ); + var category_name = category + .replace(base_category_regex, "") + .split("/")[0]; + var category_path = + base_category === "" + ? category_name + "/" + : base_category + category_name + "/"; + var name = category_name; - if(name.indexOf("::") != -1) //in case it has a namespace like "shader::math/rand" it hides the namespace + if (name.indexOf("::") != -1) + //in case it has a namespace like "shader::math/rand" it hides the namespace name = name.split("::")[1]; - - var index = entries.findIndex(function(entry){return entry.value === category_path}); + + var index = entries.findIndex(function (entry) { + return entry.value === category_path; + }); if (index === -1) { - entries.push({ value: category_path, content: name, has_submenu: true, callback : function(value, event, mouseEvent, contextMenu){ - inner_onMenuAdded(value.value, contextMenu) - }}); + entries.push({ + value: category_path, + content: name, + has_submenu: true, + callback: function ( + value, + event, + mouseEvent, + contextMenu + ) { + inner_onMenuAdded(value.value, contextMenu); + }, + }); } - }); - - var nodes = LiteGraph.getNodeTypesInCategory(base_category.slice(0, -1), canvas.filter || graph.filter ); - nodes.map(function(node){ - - if (node.skip_list) - return; - - var entry = { value: node.type, content: node.title, has_submenu: false , callback : function(value, event, mouseEvent, contextMenu){ - + + var nodes = LiteGraph.getNodeTypesInCategory( + base_category.slice(0, -1), + canvas.filter || graph.filter + ); + nodes.map(function (node) { + if (node.skip_list) return; + + var entry = { + value: node.type, + content: node.title, + has_submenu: false, + callback: function (value, event, mouseEvent, contextMenu) { var first_event = contextMenu.getFirstEvent(); canvas.graph.beforeChange(); var node = LiteGraph.createNode(value.value); if (node) { - node.pos = canvas.convertEventToCanvasOffset(first_event); + node.pos = + canvas.convertEventToCanvasOffset(first_event); canvas.graph.add(node); } - if(callback) - callback(node); + if (callback) callback(node); canvas.graph.afterChange(); - - } - } - + }, + }; + entries.push(entry); - }); - - new LiteGraph.ContextMenu( entries, { event: e, parentMenu: prev_menu }, ref_window ); - + + new LiteGraph.ContextMenu( + entries, + { event: e, parentMenu: prev_menu }, + ref_window + ); } - - inner_onMenuAdded('',prev_menu); + + inner_onMenuAdded("", prev_menu); return false; - }; - LGraphCanvas.onMenuCollapseAll = function() {}; + LGraphCanvas.onMenuCollapseAll = function () {}; - LGraphCanvas.onMenuNodeEdit = function() {}; + LGraphCanvas.onMenuNodeEdit = function () {}; - LGraphCanvas.showMenuNodeOptionalInputs = function( + LGraphCanvas.showMenuNodeOptionalInputs = function ( v, options, e, @@ -10685,21 +11419,20 @@ LGraphNode.prototype.executeAction = function(action) var entries = []; if (options) { - for (var i=0; i < options.length; i++) { + for (var i = 0; i < options.length; i++) { var entry = options[i]; if (!entry) { entries.push(null); continue; } var label = entry[0]; - if(!entry[2]) - entry[2] = {}; + if (!entry[2]) entry[2] = {}; if (entry[2].label) { label = entry[2].label; } - entry[2].removable = true; + entry[2].removable = true; var data = { content: label, value: entry }; if (entry[1] == LiteGraph.ACTION) { data.className = "event"; @@ -10710,11 +11443,11 @@ LGraphNode.prototype.executeAction = function(action) if (node.onMenuNodeInputs) { var retEntries = node.onMenuNodeInputs(entries); - if(retEntries) entries = retEntries; + if (retEntries) entries = retEntries; } if (!entries.length) { - console.log("no input entries"); + console.log("no input entries"); return; } @@ -10724,7 +11457,7 @@ LGraphNode.prototype.executeAction = function(action) event: e, callback: inner_clicked, parentMenu: prev_menu, - node: node + node: node, }, ref_window ); @@ -10739,21 +11472,22 @@ LGraphNode.prototype.executeAction = function(action) } if (v.value) { - node.graph.beforeChange(); + node.graph.beforeChange(); node.addInput(v.value[0], v.value[1], v.value[2]); - if (node.onNodeInputAdd) { // callback to the node when adding a slot + if (node.onNodeInputAdd) { + // callback to the node when adding a slot node.onNodeInputAdd(v.value); } node.setDirtyCanvas(true, true); - node.graph.afterChange(); + node.graph.afterChange(); } } return false; }; - LGraphCanvas.showMenuNodeOptionalOutputs = function( + LGraphCanvas.showMenuNodeOptionalOutputs = function ( v, options, e, @@ -10775,7 +11509,7 @@ LGraphNode.prototype.executeAction = function(action) var entries = []; if (options) { - for (var i=0; i < options.length; i++) { + for (var i = 0; i < options.length; i++) { var entry = options[i]; if (!entry) { //separator? @@ -10791,12 +11525,11 @@ LGraphNode.prototype.executeAction = function(action) continue; } //skip the ones already on var label = entry[0]; - if(!entry[2]) - entry[2] = {}; + if (!entry[2]) entry[2] = {}; if (entry[2].label) { label = entry[2].label; } - entry[2].removable = true; + entry[2].removable = true; var data = { content: label, value: entry }; if (entry[1] == LiteGraph.EVENT) { data.className = "event"; @@ -10808,15 +11541,24 @@ LGraphNode.prototype.executeAction = function(action) if (this.onMenuNodeOutputs) { entries = this.onMenuNodeOutputs(entries); } - if (LiteGraph.do_add_triggers_slots){ //canvas.allow_addOutSlot_onExecuted - if (node.findOutputSlot("onExecuted") == -1){ - entries.push({content: "On Executed", value: ["onExecuted", LiteGraph.EVENT, {nameLocked: true}], className: "event"}); //, opts: {} + if (LiteGraph.do_add_triggers_slots) { + //canvas.allow_addOutSlot_onExecuted + if (node.findOutputSlot("onExecuted") == -1) { + entries.push({ + content: "On Executed", + value: [ + "onExecuted", + LiteGraph.EVENT, + { nameLocked: true }, + ], + className: "event", + }); //, opts: {} } } // add callback for modifing the menu elements onMenuNodeOutputs if (node.onMenuNodeOutputs) { var retEntries = node.onMenuNodeOutputs(entries); - if(retEntries) entries = retEntries; + if (retEntries) entries = retEntries; } if (!entries.length) { @@ -10829,7 +11571,7 @@ LGraphNode.prototype.executeAction = function(action) event: e, callback: inner_clicked, parentMenu: prev_menu, - node: node + node: node, }, ref_window ); @@ -10862,25 +11604,26 @@ LGraphNode.prototype.executeAction = function(action) event: e, callback: inner_clicked, parentMenu: prev_menu, - node: node + node: node, }); return false; } else { - node.graph.beforeChange(); + node.graph.beforeChange(); node.addOutput(v.value[0], v.value[1], v.value[2]); - if (node.onNodeOutputAdd) { // a callback to the node when adding a slot + if (node.onNodeOutputAdd) { + // a callback to the node when adding a slot node.onNodeOutputAdd(v.value); } node.setDirtyCanvas(true, true); - node.graph.afterChange(); + node.graph.afterChange(); } } return false; }; - LGraphCanvas.onShowMenuNodeProperties = function( + LGraphCanvas.onShowMenuNodeProperties = function ( value, options, e, @@ -10897,12 +11640,15 @@ LGraphNode.prototype.executeAction = function(action) var entries = []; for (var i in node.properties) { - var value = node.properties[i] !== undefined ? node.properties[i] : " "; - if( typeof value == "object" ) - value = JSON.stringify(value); - var info = node.getPropertyInfo(i); - if(info.type == "enum" || info.type == "combo") - value = LGraphCanvas.getPropertyPrintableValue( value, info.values ); + var value = + node.properties[i] !== undefined ? node.properties[i] : " "; + if (typeof value == "object") value = JSON.stringify(value); + var info = node.getPropertyInfo(i); + if (info.type == "enum" || info.type == "combo") + value = LGraphCanvas.getPropertyPrintableValue( + value, + info.values + ); //value could contain invalid html characters, clean that value = LGraphCanvas.decodeHTML(value); @@ -10914,7 +11660,7 @@ LGraphNode.prototype.executeAction = function(action) "" + value + "", - value: i + value: i, }); } if (!entries.length) { @@ -10928,7 +11674,7 @@ LGraphNode.prototype.executeAction = function(action) callback: inner_clicked, parentMenu: prev_menu, allow_html: true, - node: node + node: node, }, ref_window ); @@ -10939,82 +11685,114 @@ LGraphNode.prototype.executeAction = function(action) } var rect = this.getBoundingClientRect(); canvas.showEditPropertyValue(node, v.value, { - position: [rect.left, rect.top] + position: [rect.left, rect.top], }); } return false; }; - LGraphCanvas.decodeHTML = function(str) { + LGraphCanvas.decodeHTML = function (str) { var e = document.createElement("div"); e.innerText = str; return e.innerHTML; }; - LGraphCanvas.onMenuResizeNode = function(value, options, e, menu, node) { + LGraphCanvas.onMenuResizeNode = function (value, options, e, menu, node) { if (!node) { return; } - - var fApplyMultiNode = function(node){ - node.size = node.computeSize(); - if (node.onResize) - node.onResize(node.size); - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - + + var fApplyMultiNode = function (node) { + node.size = node.computeSize(); + if (node.onResize) node.onResize(node.size); + }; + + var graphcanvas = LGraphCanvas.active_canvas; + if ( + !graphcanvas.selected_nodes || + Object.keys(graphcanvas.selected_nodes).length <= 1 + ) { + fApplyMultiNode(node); + } else { + for (var i in graphcanvas.selected_nodes) { + fApplyMultiNode(graphcanvas.selected_nodes[i]); + } + } + node.setDirtyCanvas(true, true); }; - LGraphCanvas.prototype.showLinkMenu = function(link, e) { + LGraphCanvas.prototype.showLinkMenu = function (link, e) { var that = this; - // console.log(link); - var node_left = that.graph.getNodeById( link.origin_id ); - var node_right = that.graph.getNodeById( link.target_id ); - var fromType = false; - if (node_left && node_left.outputs && node_left.outputs[link.origin_slot]) fromType = node_left.outputs[link.origin_slot].type; + // console.log(link); + var node_left = that.graph.getNodeById(link.origin_id); + var node_right = that.graph.getNodeById(link.target_id); + var fromType = false; + if ( + node_left && + node_left.outputs && + node_left.outputs[link.origin_slot] + ) + fromType = node_left.outputs[link.origin_slot].type; var destType = false; - if (node_right && node_right.outputs && node_right.outputs[link.target_slot]) destType = node_right.inputs[link.target_slot].type; - - var options = ["Add Node",null,"Delete",null]; - - + if ( + node_right && + node_right.outputs && + node_right.outputs[link.target_slot] + ) + destType = node_right.inputs[link.target_slot].type; + + var options = ["Add Node", null, "Delete", null]; + var menu = new LiteGraph.ContextMenu(options, { event: e, - title: link.data != null ? link.data.constructor.name : null, - callback: inner_clicked + title: link.data != null ? link.data.constructor.name : null, + callback: inner_clicked, }); - function inner_clicked(v,options,e) { + function inner_clicked(v, options, e) { switch (v) { case "Add Node": - LGraphCanvas.onMenuAdd(null, null, e, menu, function(node){ - // console.debug("node autoconnect"); - if(!node.inputs || !node.inputs.length || !node.outputs || !node.outputs.length){ - return; - } - // leave the connection type checking inside connectByType - if (node_left.connectByType( link.origin_slot, node, fromType )){ - node.connectByType( link.target_slot, node_right, destType ); - node.pos[0] -= node.size[0] * 0.5; + LGraphCanvas.onMenuAdd( + null, + null, + e, + menu, + function (node) { + // console.debug("node autoconnect"); + if ( + !node.inputs || + !node.inputs.length || + !node.outputs || + !node.outputs.length + ) { + return; + } + // leave the connection type checking inside connectByType + if ( + node_left.connectByType( + link.origin_slot, + node, + fromType + ) + ) { + node.connectByType( + link.target_slot, + node_right, + destType + ); + node.pos[0] -= node.size[0] * 0.5; + } } - }); - break; - + ); + break; + case "Delete": that.graph.removeLink(link.id); break; default: - /*var nodeCreated = createDefaultNodeForSlot({ nodeFrom: node_left + /*var nodeCreated = createDefaultNodeForSlot({ nodeFrom: node_left ,slotFrom: link.origin_slot ,nodeTo: node ,slotTo: link.target_slot @@ -11027,281 +11805,379 @@ LGraphNode.prototype.executeAction = function(action) return false; }; - - LGraphCanvas.prototype.createDefaultNodeForSlot = function(optPass) { // addNodeMenu for connection + + LGraphCanvas.prototype.createDefaultNodeForSlot = function (optPass) { + // addNodeMenu for connection var optPass = optPass || {}; - var opts = Object.assign({ nodeFrom: null // input - ,slotFrom: null // input - ,nodeTo: null // output - ,slotTo: null // output - ,position: [] // pass the event coords - ,nodeType: null // choose a nodetype to add, AUTO to set at first good - ,posAdd:[0,0] // adjust x,y - ,posSizeFix:[0,0] // alpha, adjust the position x,y based on the new node size w,h - } - ,optPass - ); + var opts = Object.assign( + { + nodeFrom: null, // input + slotFrom: null, // input + nodeTo: null, // output + slotTo: null, // output + position: [], // pass the event coords + nodeType: null, // choose a nodetype to add, AUTO to set at first good + posAdd: [0, 0], // adjust x,y + posSizeFix: [0, 0], // alpha, adjust the position x,y based on the new node size w,h + }, + optPass + ); var that = this; - - var isFrom = opts.nodeFrom && opts.slotFrom!==null; - var isTo = !isFrom && opts.nodeTo && opts.slotTo!==null; - - if (!isFrom && !isTo){ - console.warn("No data passed to createDefaultNodeForSlot "+opts.nodeFrom+" "+opts.slotFrom+" "+opts.nodeTo+" "+opts.slotTo); - return false; + + var isFrom = opts.nodeFrom && opts.slotFrom !== null; + var isTo = !isFrom && opts.nodeTo && opts.slotTo !== null; + + if (!isFrom && !isTo) { + console.warn( + "No data passed to createDefaultNodeForSlot " + + opts.nodeFrom + + " " + + opts.slotFrom + + " " + + opts.nodeTo + + " " + + opts.slotTo + ); + return false; } - if (!opts.nodeType){ + if (!opts.nodeType) { console.warn("No type to createDefaultNodeForSlot"); return false; } - + var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo; var slotX = isFrom ? opts.slotFrom : opts.slotTo; - + var iSlotConn = false; - switch (typeof slotX){ + switch (typeof slotX) { case "string": - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false); + iSlotConn = isFrom + ? nodeX.findOutputSlot(slotX, false) + : nodeX.findInputSlot(slotX, false); slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; + break; case "object": // ok slotX - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name); - break; + iSlotConn = isFrom + ? nodeX.findOutputSlot(slotX.name) + : nodeX.findInputSlot(slotX.name); + break; case "number": iSlotConn = slotX; slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; - case "undefined": + break; + case "undefined": default: // bad ? //iSlotConn = 0; - console.warn("Cant get slot information "+slotX); + console.warn("Cant get slot information " + slotX); return false; } - - if (slotX===false || iSlotConn===false){ - console.warn("createDefaultNodeForSlot bad slotX "+slotX+" "+iSlotConn); - } - - // check for defaults nodes for this slottype - var fromSlotType = slotX.type==LiteGraph.EVENT?"_event_":slotX.type; - var slotTypesDefault = isFrom ? LiteGraph.slot_types_default_out : LiteGraph.slot_types_default_in; - if(slotTypesDefault && slotTypesDefault[fromSlotType]){ - if (slotX.link !== null) { - // is connected - }else{ - // is not not connected - } - nodeNewType = false; - if(typeof slotTypesDefault[fromSlotType] == "object" || typeof slotTypesDefault[fromSlotType] == "array"){ - for(var typeX in slotTypesDefault[fromSlotType]){ - if (opts.nodeType == slotTypesDefault[fromSlotType][typeX] || opts.nodeType == "AUTO"){ - nodeNewType = slotTypesDefault[fromSlotType][typeX]; - // console.log("opts.nodeType == slotTypesDefault[fromSlotType][typeX] :: "+opts.nodeType); - break; // -------- - } - } - }else{ - if (opts.nodeType == slotTypesDefault[fromSlotType] || opts.nodeType == "AUTO") nodeNewType = slotTypesDefault[fromSlotType]; - } - if (nodeNewType) { - var nodeNewOpts = false; - if (typeof nodeNewType == "object" && nodeNewType.node){ - nodeNewOpts = nodeNewType; - nodeNewType = nodeNewType.node; - } - - //that.graph.beforeChange(); - - var newNode = LiteGraph.createNode(nodeNewType); - if(newNode){ - // if is object pass options - if (nodeNewOpts){ - if (nodeNewOpts.properties) { - for (var i in nodeNewOpts.properties) { - newNode.addProperty( i, nodeNewOpts.properties[i] ); - } - } - if (nodeNewOpts.inputs) { - newNode.inputs = []; - for (var i in nodeNewOpts.inputs) { - newNode.addOutput( - nodeNewOpts.inputs[i][0], - nodeNewOpts.inputs[i][1] - ); - } - } - if (nodeNewOpts.outputs) { - newNode.outputs = []; - for (var i in nodeNewOpts.outputs) { - newNode.addOutput( - nodeNewOpts.outputs[i][0], - nodeNewOpts.outputs[i][1] - ); - } - } - if (nodeNewOpts.title) { - newNode.title = nodeNewOpts.title; - } - if (nodeNewOpts.json) { - newNode.configure(nodeNewOpts.json); - } - - } - - // add the node - that.graph.add(newNode); - newNode.pos = [ opts.position[0]+opts.posAdd[0]+(opts.posSizeFix[0]?opts.posSizeFix[0]*newNode.size[0]:0) - ,opts.position[1]+opts.posAdd[1]+(opts.posSizeFix[1]?opts.posSizeFix[1]*newNode.size[1]:0)]; //that.last_click_position; //[e.canvasX+30, e.canvasX+5];*/ - - //that.graph.afterChange(); - - // connect the two! - if (isFrom){ - opts.nodeFrom.connectByType( iSlotConn, newNode, fromSlotType ); - }else{ - opts.nodeTo.connectByTypeOutput( iSlotConn, newNode, fromSlotType ); - } - - // if connecting in between - if (isFrom && isTo){ - // TODO - } - - return true; - - }else{ - console.log("failed creating "+nodeNewType); - } - } - } - return false; - } - - LGraphCanvas.prototype.showConnectionMenu = function(optPass) { // addNodeMenu for connection + + if (slotX === false || iSlotConn === false) { + console.warn( + "createDefaultNodeForSlot bad slotX " + slotX + " " + iSlotConn + ); + } + + // check for defaults nodes for this slottype + var fromSlotType = + slotX.type == LiteGraph.EVENT ? "_event_" : slotX.type; + var slotTypesDefault = isFrom + ? LiteGraph.slot_types_default_out + : LiteGraph.slot_types_default_in; + if (slotTypesDefault && slotTypesDefault[fromSlotType]) { + if (slotX.link !== null) { + // is connected + } else { + // is not not connected + } + nodeNewType = false; + if ( + typeof slotTypesDefault[fromSlotType] == "object" || + typeof slotTypesDefault[fromSlotType] == "array" + ) { + for (var typeX in slotTypesDefault[fromSlotType]) { + if ( + opts.nodeType == + slotTypesDefault[fromSlotType][typeX] || + opts.nodeType == "AUTO" + ) { + nodeNewType = slotTypesDefault[fromSlotType][typeX]; + // console.log("opts.nodeType == slotTypesDefault[fromSlotType][typeX] :: "+opts.nodeType); + break; // -------- + } + } + } else { + if ( + opts.nodeType == slotTypesDefault[fromSlotType] || + opts.nodeType == "AUTO" + ) + nodeNewType = slotTypesDefault[fromSlotType]; + } + if (nodeNewType) { + var nodeNewOpts = false; + if (typeof nodeNewType == "object" && nodeNewType.node) { + nodeNewOpts = nodeNewType; + nodeNewType = nodeNewType.node; + } + + //that.graph.beforeChange(); + + var newNode = LiteGraph.createNode(nodeNewType); + if (newNode) { + // if is object pass options + if (nodeNewOpts) { + if (nodeNewOpts.properties) { + for (var i in nodeNewOpts.properties) { + newNode.addProperty( + i, + nodeNewOpts.properties[i] + ); + } + } + if (nodeNewOpts.inputs) { + newNode.inputs = []; + for (var i in nodeNewOpts.inputs) { + newNode.addOutput( + nodeNewOpts.inputs[i][0], + nodeNewOpts.inputs[i][1] + ); + } + } + if (nodeNewOpts.outputs) { + newNode.outputs = []; + for (var i in nodeNewOpts.outputs) { + newNode.addOutput( + nodeNewOpts.outputs[i][0], + nodeNewOpts.outputs[i][1] + ); + } + } + if (nodeNewOpts.title) { + newNode.title = nodeNewOpts.title; + } + if (nodeNewOpts.json) { + newNode.configure(nodeNewOpts.json); + } + } + + // add the node + that.graph.add(newNode); + newNode.pos = [ + opts.position[0] + + opts.posAdd[0] + + (opts.posSizeFix[0] + ? opts.posSizeFix[0] * newNode.size[0] + : 0), + opts.position[1] + + opts.posAdd[1] + + (opts.posSizeFix[1] + ? opts.posSizeFix[1] * newNode.size[1] + : 0), + ]; //that.last_click_position; //[e.canvasX+30, e.canvasX+5];*/ + + //that.graph.afterChange(); + + // connect the two! + if (isFrom) { + opts.nodeFrom.connectByType( + iSlotConn, + newNode, + fromSlotType + ); + } else { + opts.nodeTo.connectByTypeOutput( + iSlotConn, + newNode, + fromSlotType + ); + } + + // if connecting in between + if (isFrom && isTo) { + // TODO + } + + return true; + } else { + console.log("failed creating " + nodeNewType); + } + } + } + return false; + }; + + LGraphCanvas.prototype.showConnectionMenu = function (optPass) { + // addNodeMenu for connection var optPass = optPass || {}; - var opts = Object.assign({ nodeFrom: null // input - ,slotFrom: null // input - ,nodeTo: null // output - ,slotTo: null // output - ,e: null - } - ,optPass - ); + var opts = Object.assign( + { + nodeFrom: null, // input + slotFrom: null, // input + nodeTo: null, // output + slotTo: null, // output + e: null, + }, + optPass + ); var that = this; - + var isFrom = opts.nodeFrom && opts.slotFrom; var isTo = !isFrom && opts.nodeTo && opts.slotTo; - - if (!isFrom && !isTo){ + + if (!isFrom && !isTo) { console.warn("No data passed to showConnectionMenu"); return false; } - + var nodeX = isFrom ? opts.nodeFrom : opts.nodeTo; var slotX = isFrom ? opts.slotFrom : opts.slotTo; - + var iSlotConn = false; - switch (typeof slotX){ + switch (typeof slotX) { case "string": - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX,false) : nodeX.findInputSlot(slotX,false); + iSlotConn = isFrom + ? nodeX.findOutputSlot(slotX, false) + : nodeX.findInputSlot(slotX, false); slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; + break; case "object": // ok slotX - iSlotConn = isFrom ? nodeX.findOutputSlot(slotX.name) : nodeX.findInputSlot(slotX.name); - break; + iSlotConn = isFrom + ? nodeX.findOutputSlot(slotX.name) + : nodeX.findInputSlot(slotX.name); + break; case "number": iSlotConn = slotX; slotX = isFrom ? nodeX.outputs[slotX] : nodeX.inputs[slotX]; - break; + break; default: // bad ? //iSlotConn = 0; - console.warn("Cant get slot information "+slotX); + console.warn("Cant get slot information " + slotX); return false; } - - var options = ["Add Node",null]; - - if (that.allow_searchbox){ - options.push("Search"); - options.push(null); - } - - // get defaults nodes for this slottype - var fromSlotType = slotX.type==LiteGraph.EVENT?"_event_":slotX.type; - var slotTypesDefault = isFrom ? LiteGraph.slot_types_default_out : LiteGraph.slot_types_default_in; - if(slotTypesDefault && slotTypesDefault[fromSlotType]){ - if(typeof slotTypesDefault[fromSlotType] == "object" || typeof slotTypesDefault[fromSlotType] == "array"){ - for(var typeX in slotTypesDefault[fromSlotType]){ - options.push(slotTypesDefault[fromSlotType][typeX]); - } - }else{ - options.push(slotTypesDefault[fromSlotType]); - } - } - - // build menu + + var options = ["Add Node", null]; + + if (that.allow_searchbox) { + options.push("Search"); + options.push(null); + } + + // get defaults nodes for this slottype + var fromSlotType = + slotX.type == LiteGraph.EVENT ? "_event_" : slotX.type; + var slotTypesDefault = isFrom + ? LiteGraph.slot_types_default_out + : LiteGraph.slot_types_default_in; + if (slotTypesDefault && slotTypesDefault[fromSlotType]) { + if ( + typeof slotTypesDefault[fromSlotType] == "object" || + typeof slotTypesDefault[fromSlotType] == "array" + ) { + for (var typeX in slotTypesDefault[fromSlotType]) { + options.push(slotTypesDefault[fromSlotType][typeX]); + } + } else { + options.push(slotTypesDefault[fromSlotType]); + } + } + + // build menu var menu = new LiteGraph.ContextMenu(options, { event: opts.e, - title: (slotX && slotX.name!="" ? (slotX.name + (fromSlotType?" | ":"")) : "")+(slotX && fromSlotType ? fromSlotType : ""), - callback: inner_clicked + title: + (slotX && slotX.name != "" + ? slotX.name + (fromSlotType ? " | " : "") + : "") + (slotX && fromSlotType ? fromSlotType : ""), + callback: inner_clicked, }); - - // callback - function inner_clicked(v,options,e) { + + // callback + function inner_clicked(v, options, e) { //console.log("Process showConnectionMenu selection"); switch (v) { case "Add Node": - LGraphCanvas.onMenuAdd(null, null, e, menu, function(node){ - if (isFrom){ - opts.nodeFrom.connectByType( iSlotConn, node, fromSlotType ); - }else{ - opts.nodeTo.connectByTypeOutput( iSlotConn, node, fromSlotType ); + LGraphCanvas.onMenuAdd( + null, + null, + e, + menu, + function (node) { + if (isFrom) { + opts.nodeFrom.connectByType( + iSlotConn, + node, + fromSlotType + ); + } else { + opts.nodeTo.connectByTypeOutput( + iSlotConn, + node, + fromSlotType + ); + } } - }); + ); + break; + case "Search": + if (isFrom) { + that.showSearchBox(e, { + node_from: opts.nodeFrom, + slot_from: slotX, + type_filter_in: fromSlotType, + }); + } else { + that.showSearchBox(e, { + node_to: opts.nodeTo, + slot_from: slotX, + type_filter_out: fromSlotType, + }); + } break; - case "Search": - if(isFrom){ - that.showSearchBox(e,{node_from: opts.nodeFrom, slot_from: slotX, type_filter_in: fromSlotType}); - }else{ - that.showSearchBox(e,{node_to: opts.nodeTo, slot_from: slotX, type_filter_out: fromSlotType}); - } - break; default: - // check for defaults nodes for this slottype - var nodeCreated = that.createDefaultNodeForSlot(Object.assign(opts,{ position: [opts.e.canvasX, opts.e.canvasY] - ,nodeType: v - })); - if (nodeCreated){ - // new node created - //console.log("node "+v+" created") - }else{ - // failed or v is not in defaults - } - break; - } - } - + // check for defaults nodes for this slottype + var nodeCreated = that.createDefaultNodeForSlot( + Object.assign(opts, { + position: [opts.e.canvasX, opts.e.canvasY], + nodeType: v, + }) + ); + if (nodeCreated) { + // new node created + //console.log("node "+v+" created") + } else { + // failed or v is not in defaults + } + break; + } + } + return false; }; // TODO refactor :: this is used fot title but not for properties! - LGraphCanvas.onShowPropertyEditor = function(item, options, e, menu, node) { + LGraphCanvas.onShowPropertyEditor = function ( + item, + options, + e, + menu, + node + ) { var input_html = ""; var property = item.property || "title"; var value = node[property]; // TODO refactor :: use createDialog ? - + var dialog = document.createElement("div"); dialog.is_modified = false; dialog.className = "graphdialog"; dialog.innerHTML = ""; - dialog.close = function() { + dialog.close = function () { if (dialog.parentNode) { dialog.parentNode.removeChild(dialog); } @@ -11311,17 +12187,20 @@ LGraphNode.prototype.executeAction = function(action) var input = dialog.querySelector(".value"); if (input) { input.value = value; - input.addEventListener("blur", function(e) { + input.addEventListener("blur", function (e) { this.focus(); }); - input.addEventListener("keydown", function(e) { + input.addEventListener("keydown", function (e) { dialog.is_modified = true; if (e.keyCode == 27) { //ESC dialog.close(); } else if (e.keyCode == 13) { inner(); // save - } else if (e.keyCode != 13 && e.target.localName != "textarea") { + } else if ( + e.keyCode != 13 && + e.target.localName != "textarea" + ) { return; } e.preventDefault(); @@ -11352,21 +12231,27 @@ LGraphNode.prototype.executeAction = function(action) button.addEventListener("click", inner); canvas.parentNode.appendChild(dialog); - if(input) input.focus(); - + if (input) input.focus(); + var dialogCloseTimer = null; - dialog.addEventListener("mouseleave", function(e) { - if(LiteGraph.dialog_close_on_mouse_leave) - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) - dialogCloseTimer = setTimeout(dialog.close, LiteGraph.dialog_close_on_mouse_leave_delay); //dialog.close(); + dialog.addEventListener("mouseleave", function (e) { + if (LiteGraph.dialog_close_on_mouse_leave) + if ( + !dialog.is_modified && + LiteGraph.dialog_close_on_mouse_leave + ) + dialogCloseTimer = setTimeout( + dialog.close, + LiteGraph.dialog_close_on_mouse_leave_delay + ); //dialog.close(); }); - dialog.addEventListener("mouseenter", function(e) { - if(LiteGraph.dialog_close_on_mouse_leave) - if(dialogCloseTimer) clearTimeout(dialogCloseTimer); + dialog.addEventListener("mouseenter", function (e) { + if (LiteGraph.dialog_close_on_mouse_leave) + if (dialogCloseTimer) clearTimeout(dialogCloseTimer); }); - + function inner() { - if(input) setValue(input.value); + if (input) setValue(input.value); } function setValue(value) { @@ -11384,7 +12269,13 @@ LGraphNode.prototype.executeAction = function(action) }; // refactor: there are different dialogs, some uses createDialog some dont - LGraphCanvas.prototype.prompt = function(title, value, callback, event, multiline) { + LGraphCanvas.prototype.prompt = function ( + title, + value, + callback, + event, + multiline + ) { var that = this; var input_html = ""; title = title || ""; @@ -11392,11 +12283,13 @@ LGraphNode.prototype.executeAction = function(action) var dialog = document.createElement("div"); dialog.is_modified = false; dialog.className = "graphdialog rounded"; - if(multiline) - dialog.innerHTML = " "; - else - dialog.innerHTML = " "; - dialog.close = function() { + if (multiline) + dialog.innerHTML = + " "; + else + dialog.innerHTML = + " "; + dialog.close = function () { that.prompt_box = null; if (dialog.parentNode) { dialog.parentNode.removeChild(dialog); @@ -11406,35 +12299,40 @@ LGraphNode.prototype.executeAction = function(action) var graphcanvas = LGraphCanvas.active_canvas; var canvas = graphcanvas.canvas; canvas.parentNode.appendChild(dialog); - + if (this.ds.scale > 1) { dialog.style.transform = "scale(" + this.ds.scale + ")"; } var dialogCloseTimer = null; var prevent_timeout = false; - LiteGraph.pointerListenerAdd(dialog,"leave", function(e) { - if (prevent_timeout) - return; - if(LiteGraph.dialog_close_on_mouse_leave) - if (!dialog.is_modified && LiteGraph.dialog_close_on_mouse_leave) - dialogCloseTimer = setTimeout(dialog.close, LiteGraph.dialog_close_on_mouse_leave_delay); //dialog.close(); + LiteGraph.pointerListenerAdd(dialog, "leave", function (e) { + if (prevent_timeout) return; + if (LiteGraph.dialog_close_on_mouse_leave) + if ( + !dialog.is_modified && + LiteGraph.dialog_close_on_mouse_leave + ) + dialogCloseTimer = setTimeout( + dialog.close, + LiteGraph.dialog_close_on_mouse_leave_delay + ); //dialog.close(); }); - LiteGraph.pointerListenerAdd(dialog,"enter", function(e) { - if(LiteGraph.dialog_close_on_mouse_leave) - if(dialogCloseTimer) clearTimeout(dialogCloseTimer); + LiteGraph.pointerListenerAdd(dialog, "enter", function (e) { + if (LiteGraph.dialog_close_on_mouse_leave) + if (dialogCloseTimer) clearTimeout(dialogCloseTimer); }); var selInDia = dialog.querySelectorAll("select"); - if (selInDia){ + if (selInDia) { // if filtering, check focus changed to comboboxes and prevent closing - selInDia.forEach(function(selIn) { - selIn.addEventListener("click", function(e) { + selInDia.forEach(function (selIn) { + selIn.addEventListener("click", function (e) { prevent_timeout++; }); - selIn.addEventListener("blur", function(e) { - prevent_timeout = 0; + selIn.addEventListener("blur", function (e) { + prevent_timeout = 0; }); - selIn.addEventListener("change", function(e) { + selIn.addEventListener("change", function (e) { prevent_timeout = -1; }); }); @@ -11455,7 +12353,7 @@ LGraphNode.prototype.executeAction = function(action) value_element.value = value; var input = value_element; - input.addEventListener("keydown", function(e) { + input.addEventListener("keydown", function (e) { dialog.is_modified = true; if (e.keyCode == 27) { //ESC @@ -11473,7 +12371,7 @@ LGraphNode.prototype.executeAction = function(action) }); var button = dialog.querySelector("button"); - button.addEventListener("click", function(e) { + button.addEventListener("click", function (e) { if (callback) { callback(input.value); } @@ -11497,7 +12395,7 @@ LGraphNode.prototype.executeAction = function(action) dialog.style.top = canvas.height * 0.5 + offsety + "px"; } - setTimeout(function() { + setTimeout(function () { input.focus(); }, 10); @@ -11505,24 +12403,25 @@ LGraphNode.prototype.executeAction = function(action) }; LGraphCanvas.search_limit = -1; - LGraphCanvas.prototype.showSearchBox = function(event, options) { + LGraphCanvas.prototype.showSearchBox = function (event, options) { // proposed defaults - var def_options = { slot_from: null - ,node_from: null - ,node_to: null - ,do_type_filter: LiteGraph.search_filter_enabled // TODO check for registered_slot_[in/out]_types not empty // this will be checked for functionality enabled : filter on slot type, in and out - ,type_filter_in: false // these are default: pass to set initially set values - ,type_filter_out: false - ,show_general_if_none_on_typefilter: true - ,show_general_after_typefiltered: true - ,hide_on_mouse_leave: LiteGraph.search_hide_on_mouse_leave - ,show_all_if_empty: true - ,show_all_on_open: LiteGraph.search_show_all_on_open - }; + var def_options = { + slot_from: null, + node_from: null, + node_to: null, + do_type_filter: LiteGraph.search_filter_enabled, // TODO check for registered_slot_[in/out]_types not empty // this will be checked for functionality enabled : filter on slot type, in and out + type_filter_in: false, // these are default: pass to set initially set values + type_filter_out: false, + show_general_if_none_on_typefilter: true, + show_general_after_typefiltered: true, + hide_on_mouse_leave: LiteGraph.search_hide_on_mouse_leave, + show_all_if_empty: true, + show_all_on_open: LiteGraph.search_show_all_on_open, + }; options = Object.assign(def_options, options || {}); - - //console.log(options); - + + //console.log(options); + var that = this; var input_html = ""; var graphcanvas = LGraphCanvas.active_canvas; @@ -11531,34 +12430,36 @@ LGraphNode.prototype.executeAction = function(action) var dialog = document.createElement("div"); dialog.className = "litegraph litesearchbox graphdialog rounded"; - dialog.innerHTML = "Search "; - if (options.do_type_filter){ - dialog.innerHTML += ""; - dialog.innerHTML += ""; + dialog.innerHTML = + "Search "; + if (options.do_type_filter) { + dialog.innerHTML += + ""; + dialog.innerHTML += + ""; } dialog.innerHTML += "
"; - - if( root_document.fullscreenElement ) - root_document.fullscreenElement.appendChild(dialog); - else - { - root_document.body.appendChild(dialog); - root_document.body.style.overflow = "hidden"; - } + + if (root_document.fullscreenElement) + root_document.fullscreenElement.appendChild(dialog); + else { + root_document.body.appendChild(dialog); + root_document.body.style.overflow = "hidden"; + } // dialog element has been appended - - if (options.do_type_filter){ + + if (options.do_type_filter) { var selIn = dialog.querySelector(".slot_in_type_filter"); var selOut = dialog.querySelector(".slot_out_type_filter"); } - - dialog.close = function() { + + dialog.close = function () { that.search_box = null; - this.blur(); + this.blur(); canvas.focus(); - root_document.body.style.overflow = ""; + root_document.body.style.overflow = ""; - setTimeout(function() { + setTimeout(function () { that.canvas.focus(); }, 20); //important, if canvas loses focus keys wont be captured if (dialog.parentNode) { @@ -11571,41 +12472,41 @@ LGraphNode.prototype.executeAction = function(action) } // hide on mouse leave - if(options.hide_on_mouse_leave){ + if (options.hide_on_mouse_leave) { var prevent_timeout = false; var timeout_close = null; - LiteGraph.pointerListenerAdd(dialog,"enter", function(e) { + LiteGraph.pointerListenerAdd(dialog, "enter", function (e) { if (timeout_close) { clearTimeout(timeout_close); timeout_close = null; } }); - LiteGraph.pointerListenerAdd(dialog,"leave", function(e) { - if (prevent_timeout){ + LiteGraph.pointerListenerAdd(dialog, "leave", function (e) { + if (prevent_timeout) { return; } - timeout_close = setTimeout(function() { + timeout_close = setTimeout(function () { dialog.close(); }, 500); }); // if filtering, check focus changed to comboboxes and prevent closing - if (options.do_type_filter){ - selIn.addEventListener("click", function(e) { + if (options.do_type_filter) { + selIn.addEventListener("click", function (e) { prevent_timeout++; }); - selIn.addEventListener("blur", function(e) { - prevent_timeout = 0; + selIn.addEventListener("blur", function (e) { + prevent_timeout = 0; }); - selIn.addEventListener("change", function(e) { + selIn.addEventListener("change", function (e) { prevent_timeout = -1; }); - selOut.addEventListener("click", function(e) { + selOut.addEventListener("click", function (e) { prevent_timeout++; }); - selOut.addEventListener("blur", function(e) { - prevent_timeout = 0; + selOut.addEventListener("blur", function (e) { + prevent_timeout = 0; }); - selOut.addEventListener("change", function(e) { + selOut.addEventListener("change", function (e) { prevent_timeout = -1; }); } @@ -11624,11 +12525,10 @@ LGraphNode.prototype.executeAction = function(action) var input = dialog.querySelector("input"); if (input) { - input.addEventListener("blur", function(e) { - if(that.search_box) - this.focus(); + input.addEventListener("blur", function (e) { + if (that.search_box) this.focus(); }); - input.addEventListener("keydown", function(e) { + input.addEventListener("keydown", function (e) { if (e.keyCode == 38) { //UP changeSelection(false); @@ -11656,79 +12556,93 @@ LGraphNode.prototype.executeAction = function(action) } e.preventDefault(); e.stopPropagation(); - e.stopImmediatePropagation(); - return true; + e.stopImmediatePropagation(); + return true; }); } - + // if should filter on type, load and fill selected and choose elements if passed - if (options.do_type_filter){ - if (selIn){ + if (options.do_type_filter) { + if (selIn) { var aSlots = LiteGraph.slot_types_in; var nSlots = aSlots.length; // this for object :: Object.keys(aSlots).length; - - if (options.type_filter_in == LiteGraph.EVENT || options.type_filter_in == LiteGraph.ACTION) + + if ( + options.type_filter_in == LiteGraph.EVENT || + options.type_filter_in == LiteGraph.ACTION + ) options.type_filter_in = "_event_"; /* this will filter on * .. but better do it manually in case else if(options.type_filter_in === "" || options.type_filter_in === 0) options.type_filter_in = "*";*/ - - for (var iK=0; iK (rect.height - 200)) - helper.style.maxHeight = (rect.height - event.layerY - 20) + "px"; + //To avoid out of screen problems + if (event.layerY > rect.height - 200) + helper.style.maxHeight = rect.height - event.layerY - 20 + "px"; - /* + /* var offsetx = -20; var offsety = -20; if (rect) { @@ -11759,19 +12673,18 @@ LGraphNode.prototype.executeAction = function(action) name = extra.type; } - graphcanvas.graph.beforeChange(); + graphcanvas.graph.beforeChange(); var node = LiteGraph.createNode(name); if (node) { - node.pos = graphcanvas.convertEventToCanvasOffset( - event - ); + node.pos = + graphcanvas.convertEventToCanvasOffset(event); graphcanvas.graph.add(node, false); } if (extra && extra.data) { if (extra.data.properties) { for (var i in extra.data.properties) { - node.addProperty( i, extra.data.properties[i] ); + node.addProperty(i, extra.data.properties[i]); } } if (extra.data.inputs) { @@ -11798,68 +12711,95 @@ LGraphNode.prototype.executeAction = function(action) if (extra.data.json) { node.configure(extra.data.json); } - } // join node after inserting - if (options.node_from){ + if (options.node_from) { var iS = false; - switch (typeof options.slot_from){ + switch (typeof options.slot_from) { case "string": - iS = options.node_from.findOutputSlot(options.slot_from); - break; + iS = options.node_from.findOutputSlot( + options.slot_from + ); + break; case "object": - if (options.slot_from.name){ - iS = options.node_from.findOutputSlot(options.slot_from.name); - }else{ + if (options.slot_from.name) { + iS = options.node_from.findOutputSlot( + options.slot_from.name + ); + } else { iS = -1; } - if (iS==-1 && typeof options.slot_from.slot_index !== "undefined") iS = options.slot_from.slot_index; - break; + if ( + iS == -1 && + typeof options.slot_from.slot_index !== + "undefined" + ) + iS = options.slot_from.slot_index; + break; case "number": iS = options.slot_from; - break; + break; default: iS = 0; // try with first if no name set } - if (typeof options.node_from.outputs[iS] !== "undefined"){ - if (iS!==false && iS>-1){ - options.node_from.connectByType( iS, node, options.node_from.outputs[iS].type ); + if ( + typeof options.node_from.outputs[iS] !== "undefined" + ) { + if (iS !== false && iS > -1) { + options.node_from.connectByType( + iS, + node, + options.node_from.outputs[iS].type + ); } - }else{ + } else { // console.warn("cant find slot " + options.slot_from); } } - if (options.node_to){ + if (options.node_to) { var iS = false; - switch (typeof options.slot_from){ + switch (typeof options.slot_from) { case "string": - iS = options.node_to.findInputSlot(options.slot_from); - break; + iS = options.node_to.findInputSlot( + options.slot_from + ); + break; case "object": - if (options.slot_from.name){ - iS = options.node_to.findInputSlot(options.slot_from.name); - }else{ + if (options.slot_from.name) { + iS = options.node_to.findInputSlot( + options.slot_from.name + ); + } else { iS = -1; } - if (iS==-1 && typeof options.slot_from.slot_index !== "undefined") iS = options.slot_from.slot_index; - break; + if ( + iS == -1 && + typeof options.slot_from.slot_index !== + "undefined" + ) + iS = options.slot_from.slot_index; + break; case "number": iS = options.slot_from; - break; + break; default: iS = 0; // try with first if no name set } - if (typeof options.node_to.inputs[iS] !== "undefined"){ - if (iS!==false && iS>-1){ + if (typeof options.node_to.inputs[iS] !== "undefined") { + if (iS !== false && iS > -1) { // try connection - options.node_to.connectByTypeOutput(iS,node,options.node_to.inputs[iS].type); + options.node_to.connectByTypeOutput( + iS, + node, + options.node_to.inputs[iS].type + ); } - }else{ + } else { // console.warn("cant find slot_nodeTO " + options.slot_from); } } - + graphcanvas.graph.afterChange(); } } @@ -11888,7 +12828,7 @@ LGraphNode.prototype.executeAction = function(action) return; } selected.classList.add("selected"); - selected.scrollIntoView({block: "end", behavior: "smooth"}); + selected.scrollIntoView({ block: "end", behavior: "smooth" }); } function refreshHelper() { @@ -11910,136 +12850,180 @@ LGraphNode.prototype.executeAction = function(action) } else { var c = 0; str = str.toLowerCase(); - var filter = graphcanvas.filter || graphcanvas.graph.filter; + var filter = graphcanvas.filter || graphcanvas.graph.filter; // filter by type preprocess - if(options.do_type_filter && that.search_box){ - var sIn = that.search_box.querySelector(".slot_in_type_filter"); - var sOut = that.search_box.querySelector(".slot_out_type_filter"); - }else{ + if (options.do_type_filter && that.search_box) { + var sIn = that.search_box.querySelector( + ".slot_in_type_filter" + ); + var sOut = that.search_box.querySelector( + ".slot_out_type_filter" + ); + } else { var sIn = false; var sOut = false; } - + //extras for (var i in LiteGraph.searchbox_extras) { var extra = LiteGraph.searchbox_extras[i]; - if ((!options.show_all_if_empty || str) && extra.desc.toLowerCase().indexOf(str) === -1) { + if ( + (!options.show_all_if_empty || str) && + extra.desc.toLowerCase().indexOf(str) === -1 + ) { continue; } - var ctor = LiteGraph.registered_node_types[ extra.type ]; - if( ctor && ctor.filter != filter ) - continue; - if( ! inner_test_filter(extra.type) ) - continue; - addResult( extra.desc, "searchbox_extra" ); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { + var ctor = LiteGraph.registered_node_types[extra.type]; + if (ctor && ctor.filter != filter) continue; + if (!inner_test_filter(extra.type)) continue; + addResult(extra.desc, "searchbox_extra"); + if ( + LGraphCanvas.search_limit !== -1 && + c++ > LGraphCanvas.search_limit + ) { break; } } - var filtered = null; - if (Array.prototype.filter) { //filter supported - var keys = Object.keys( LiteGraph.registered_node_types ); //types - var filtered = keys.filter( inner_test_filter ); + var filtered = null; + if (Array.prototype.filter) { + //filter supported + var keys = Object.keys(LiteGraph.registered_node_types); //types + var filtered = keys.filter(inner_test_filter); } else { - filtered = []; + filtered = []; for (var i in LiteGraph.registered_node_types) { - if( inner_test_filter(i) ) - filtered.push(i); + if (inner_test_filter(i)) filtered.push(i); + } + } + + for (var i = 0; i < filtered.length; i++) { + addResult(filtered[i]); + if ( + LGraphCanvas.search_limit !== -1 && + c++ > LGraphCanvas.search_limit + ) { + break; } } - for (var i = 0; i < filtered.length; i++) { - addResult(filtered[i]); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { - break; - } - } - // add general type if filtering - if (options.show_general_after_typefiltered - && (sIn.value || sOut.value) - ){ + if ( + options.show_general_after_typefiltered && + (sIn.value || sOut.value) + ) { filtered_extra = []; for (var i in LiteGraph.registered_node_types) { - if( inner_test_filter(i, {inTypeOverride: sIn&&sIn.value?"*":false, outTypeOverride: sOut&&sOut.value?"*":false}) ) - filtered_extra.push(i); + if ( + inner_test_filter(i, { + inTypeOverride: sIn && sIn.value ? "*" : false, + outTypeOverride: + sOut && sOut.value ? "*" : false, + }) + ) + filtered_extra.push(i); } for (var i = 0; i < filtered_extra.length; i++) { addResult(filtered_extra[i], "generic_type"); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { + if ( + LGraphCanvas.search_limit !== -1 && + c++ > LGraphCanvas.search_limit + ) { break; } } } - + // check il filtering gave no results - if ((sIn.value || sOut.value) && - ( (helper.childNodes.length == 0 && options.show_general_if_none_on_typefilter) ) - ){ + if ( + (sIn.value || sOut.value) && + helper.childNodes.length == 0 && + options.show_general_if_none_on_typefilter + ) { filtered_extra = []; for (var i in LiteGraph.registered_node_types) { - if( inner_test_filter(i, {skipFilter: true}) ) - filtered_extra.push(i); + if (inner_test_filter(i, { skipFilter: true })) + filtered_extra.push(i); } for (var i = 0; i < filtered_extra.length; i++) { addResult(filtered_extra[i], "not_in_filter"); - if ( LGraphCanvas.search_limit !== -1 && c++ > LGraphCanvas.search_limit ) { + if ( + LGraphCanvas.search_limit !== -1 && + c++ > LGraphCanvas.search_limit + ) { break; } } } - - function inner_test_filter( type, optsIn ) - { + + function inner_test_filter(type, optsIn) { var optsIn = optsIn || {}; - var optsDef = { skipFilter: false - ,inTypeOverride: false - ,outTypeOverride: false - }; - var opts = Object.assign(optsDef,optsIn); - var ctor = LiteGraph.registered_node_types[ type ]; - if(filter && ctor.filter != filter ) - return false; - if ((!options.show_all_if_empty || str) && type.toLowerCase().indexOf(str) === -1) + var optsDef = { + skipFilter: false, + inTypeOverride: false, + outTypeOverride: false, + }; + var opts = Object.assign(optsDef, optsIn); + var ctor = LiteGraph.registered_node_types[type]; + if (filter && ctor.filter != filter) return false; + if ( + (!options.show_all_if_empty || str) && + type.toLowerCase().indexOf(str) === -1 + ) return false; - + // filter by slot IN, OUT types - if(options.do_type_filter && !opts.skipFilter){ + if (options.do_type_filter && !opts.skipFilter) { var sType = type; - + var sV = sIn.value; - if (opts.inTypeOverride!==false) sV = opts.inTypeOverride; - //if (sV.toLowerCase() == "_event_") sV = LiteGraph.EVENT; // -1 - - if(sIn && sV){ + if (opts.inTypeOverride !== false) + sV = opts.inTypeOverride; + //if (sV.toLowerCase() == "_event_") sV = LiteGraph.EVENT; // -1 + + if (sIn && sV) { //console.log("will check filter against "+sV); - if (LiteGraph.registered_slot_in_types[sV] && LiteGraph.registered_slot_in_types[sV].nodes){ // type is stored + if ( + LiteGraph.registered_slot_in_types[sV] && + LiteGraph.registered_slot_in_types[sV].nodes + ) { + // type is stored //console.debug("check "+sType+" in "+LiteGraph.registered_slot_in_types[sV].nodes); - var doesInc = LiteGraph.registered_slot_in_types[sV].nodes.includes(sType); - if (doesInc!==false){ + var doesInc = + LiteGraph.registered_slot_in_types[ + sV + ].nodes.includes(sType); + if (doesInc !== false) { //console.log(sType+" HAS "+sV); - }else{ + } else { /*console.debug(LiteGraph.registered_slot_in_types[sV]); console.log(+" DONT includes "+type);*/ return false; } } } - + var sV = sOut.value; - if (opts.outTypeOverride!==false) sV = opts.outTypeOverride; + if (opts.outTypeOverride !== false) + sV = opts.outTypeOverride; //if (sV.toLowerCase() == "_event_") sV = LiteGraph.EVENT; // -1 - - if(sOut && sV){ + + if (sOut && sV) { //console.log("search will check filter against "+sV); - if (LiteGraph.registered_slot_out_types[sV] && LiteGraph.registered_slot_out_types[sV].nodes){ // type is stored + if ( + LiteGraph.registered_slot_out_types[sV] && + LiteGraph.registered_slot_out_types[sV].nodes + ) { + // type is stored //console.debug("check "+sType+" in "+LiteGraph.registered_slot_out_types[sV].nodes); - var doesInc = LiteGraph.registered_slot_out_types[sV].nodes.includes(sType); - if (doesInc!==false){ + var doesInc = + LiteGraph.registered_slot_out_types[ + sV + ].nodes.includes(sType); + if (doesInc !== false) { //console.log(sType+" HAS "+sV); - }else{ + } else { /*console.debug(LiteGraph.registered_slot_out_types[sV]); console.log(+" DONT includes "+type);*/ return false; @@ -12048,7 +13032,7 @@ LGraphNode.prototype.executeAction = function(action) } } return true; - } + } } function addResult(type, className) { @@ -12062,7 +13046,7 @@ LGraphNode.prototype.executeAction = function(action) if (className) { help.className += " " + className; } - help.addEventListener("click", function(e) { + help.addEventListener("click", function (e) { select(unescape(this.dataset["type"])); }); helper.appendChild(help); @@ -12072,7 +13056,11 @@ LGraphNode.prototype.executeAction = function(action) return dialog; }; - LGraphCanvas.prototype.showEditPropertyValue = function( node, property, options ) { + LGraphCanvas.prototype.showEditPropertyValue = function ( + node, + property, + options + ) { if (!node || node.properties[property] === undefined) { return; } @@ -12081,18 +13069,22 @@ LGraphNode.prototype.executeAction = function(action) var that = this; var info = node.getPropertyInfo(property); - var type = info.type; + var type = info.type; var input_html = ""; - if (type == "string" || type == "number" || type == "array" || type == "object") { + if ( + type == "string" || + type == "number" || + type == "array" || + type == "object" + ) { input_html = ""; - } else if ( (type == "enum" || type == "combo") && info.values) { + } else if ((type == "enum" || type == "combo") && info.values) { input_html = ""; - var textarea = panel.alt_content.querySelector("textarea"); - var fDoneWith = function(){ - panel.toggleAltContent(false); //if(node_prop_div) node_prop_div.style.display = "block"; // panel.close(); - panel.toggleFooterVisibility(true); - textarea.parentNode.removeChild(textarea); - panel.classList.add("settings"); - panel.classList.remove("centered"); - inner_refresh(); - } - textarea.value = node.properties[propname]; - textarea.addEventListener("keydown", function(e){ - if(e.code == "Enter" && e.ctrlKey ) - { - node.setProperty(propname, textarea.value); - fDoneWith(); - } - }); - panel.toggleAltContent(true); - panel.toggleFooterVisibility(false); - textarea.style.height = "calc(100% - 40px)"; - /*}*/ - var assign = panel.addButton( "Assign", function(){ - node.setProperty(propname, textarea.value); + panel.alt_content.innerHTML = ""; + var textarea = panel.alt_content.querySelector("textarea"); + var fDoneWith = function () { + panel.toggleAltContent(false); //if(node_prop_div) node_prop_div.style.display = "block"; // panel.close(); + panel.toggleFooterVisibility(true); + textarea.parentNode.removeChild(textarea); + panel.classList.add("settings"); + panel.classList.remove("centered"); + inner_refresh(); + }; + textarea.value = node.properties[propname]; + textarea.addEventListener("keydown", function (e) { + if (e.code == "Enter" && e.ctrlKey) { + node.setProperty(propname, textarea.value); + fDoneWith(); + } + }); + panel.toggleAltContent(true); + panel.toggleFooterVisibility(false); + textarea.style.height = "calc(100% - 40px)"; + /*}*/ + var assign = panel.addButton("Assign", function () { + node.setProperty(propname, textarea.value); fDoneWith(); - }); - panel.alt_content.appendChild(assign); //panel.content.appendChild(assign); - var button = panel.addButton( "Close", fDoneWith); - button.style.float = "right"; - panel.alt_content.appendChild(button); // panel.content.appendChild(button); - } + }); + panel.alt_content.appendChild(assign); //panel.content.appendChild(assign); + var button = panel.addButton("Close", fDoneWith); + button.style.float = "right"; + panel.alt_content.appendChild(button); // panel.content.appendChild(button); + }; + + inner_refresh(); + + this.canvas.parentNode.appendChild(panel); + }; - inner_refresh(); + LGraphCanvas.prototype.showSubgraphPropertiesDialog = function (node) { + console.log("showing subgraph properties dialog"); + + var old_panel = + this.canvas.parentNode.querySelector(".subgraph_dialog"); + if (old_panel) old_panel.close(); + + var panel = this.createPanel("Subgraph Inputs", { + closable: true, + width: 500, + }); + panel.node = node; + panel.classList.add("subgraph_dialog"); + + function inner_refresh() { + panel.clear(); + + //show currents + if (node.inputs) + for (var i = 0; i < node.inputs.length; ++i) { + var input = node.inputs[i]; + if (input.not_subgraph_input) continue; + var html = + " "; + var elem = panel.addHTML(html, "subgraph_property"); + elem.dataset["name"] = input.name; + elem.dataset["slot"] = i; + elem.querySelector(".name").innerText = input.name; + elem.querySelector(".type").innerText = input.type; + elem.querySelector("button").addEventListener( + "click", + function (e) { + node.removeInput( + Number(this.parentNode.dataset["slot"]) + ); + inner_refresh(); + } + ); + } + } + + //add extra + var html = + " + NameType"; + var elem = panel.addHTML(html, "subgraph_property extra", true); + elem.querySelector("button").addEventListener("click", function (e) { + var elem = this.parentNode; + var name = elem.querySelector(".name").value; + var type = elem.querySelector(".type").value; + if (!name || node.findInputSlot(name) != -1) return; + node.addInput(name, type); + elem.querySelector(".name").value = ""; + elem.querySelector(".type").value = ""; + inner_refresh(); + }); - this.canvas.parentNode.appendChild( panel ); - } - - LGraphCanvas.prototype.showSubgraphPropertiesDialog = function(node) - { - console.log("showing subgraph properties dialog"); - - var old_panel = this.canvas.parentNode.querySelector(".subgraph_dialog"); - if(old_panel) - old_panel.close(); - - var panel = this.createPanel("Subgraph Inputs",{closable:true, width: 500}); - panel.node = node; - panel.classList.add("subgraph_dialog"); - - function inner_refresh() - { - panel.clear(); - - //show currents - if(node.inputs) - for(var i = 0; i < node.inputs.length; ++i) - { - var input = node.inputs[i]; - if(input.not_subgraph_input) - continue; - var html = " "; - var elem = panel.addHTML(html,"subgraph_property"); - elem.dataset["name"] = input.name; - elem.dataset["slot"] = i; - elem.querySelector(".name").innerText = input.name; - elem.querySelector(".type").innerText = input.type; - elem.querySelector("button").addEventListener("click",function(e){ - node.removeInput( Number( this.parentNode.dataset["slot"] ) ); - inner_refresh(); - }); - } - } - - //add extra - var html = " + NameType"; - var elem = panel.addHTML(html,"subgraph_property extra", true); - elem.querySelector("button").addEventListener("click", function(e){ - var elem = this.parentNode; - var name = elem.querySelector(".name").value; - var type = elem.querySelector(".type").value; - if(!name || node.findInputSlot(name) != -1) - return; - node.addInput(name,type); - elem.querySelector(".name").value = ""; - elem.querySelector(".type").value = ""; - inner_refresh(); - }); - - inner_refresh(); - this.canvas.parentNode.appendChild(panel); - return panel; - } + inner_refresh(); + this.canvas.parentNode.appendChild(panel); + return panel; + }; LGraphCanvas.prototype.showSubgraphPropertiesDialogRight = function (node) { - // console.log("showing subgraph properties dialog"); var that = this; // old_panel if old_panel is exist close it - var old_panel = this.canvas.parentNode.querySelector(".subgraph_dialog"); - if (old_panel) - old_panel.close(); + var old_panel = + this.canvas.parentNode.querySelector(".subgraph_dialog"); + if (old_panel) old_panel.close(); // new panel - var panel = this.createPanel("Subgraph Outputs", { closable: true, width: 500 }); + var panel = this.createPanel("Subgraph Outputs", { + closable: true, + width: 500, + }); panel.node = node; panel.classList.add("subgraph_dialog"); @@ -12849,38 +13920,43 @@ LGraphNode.prototype.executeAction = function(action) if (node.outputs) for (var i = 0; i < node.outputs.length; ++i) { var input = node.outputs[i]; - if (input.not_subgraph_output) - continue; - var html = " "; + if (input.not_subgraph_output) continue; + var html = + " "; var elem = panel.addHTML(html, "subgraph_property"); elem.dataset["name"] = input.name; elem.dataset["slot"] = i; elem.querySelector(".name").innerText = input.name; elem.querySelector(".type").innerText = input.type; - elem.querySelector("button").addEventListener("click", function (e) { - node.removeOutput(Number(this.parentNode.dataset["slot"])); - inner_refresh(); - }); + elem.querySelector("button").addEventListener( + "click", + function (e) { + node.removeOutput( + Number(this.parentNode.dataset["slot"]) + ); + inner_refresh(); + } + ); } } //add extra - var html = " + NameType"; + var html = + " + NameType"; var elem = panel.addHTML(html, "subgraph_property extra", true); elem.querySelector(".name").addEventListener("keydown", function (e) { if (e.keyCode == 13) { - addOutput.apply(this) + addOutput.apply(this); } - }) + }); elem.querySelector("button").addEventListener("click", function (e) { - addOutput.apply(this) + addOutput.apply(this); }); function addOutput() { var elem = this.parentNode; var name = elem.querySelector(".name").value; var type = elem.querySelector(".type").value; - if (!name || node.findOutputSlot(name) != -1) - return; + if (!name || node.findOutputSlot(name) != -1) return; node.addOutput(name, type); elem.querySelector(".name").value = ""; elem.querySelector(".type").value = ""; @@ -12890,79 +13966,82 @@ LGraphNode.prototype.executeAction = function(action) inner_refresh(); this.canvas.parentNode.appendChild(panel); return panel; - } - LGraphCanvas.prototype.checkPanels = function() - { - if(!this.canvas) - return; - var panels = this.canvas.parentNode.querySelectorAll(".litegraph.dialog"); - for(var i = 0; i < panels.length; ++i) - { - var panel = panels[i]; - if( !panel.node ) - continue; - if( !panel.node.graph || panel.graph != this.graph ) - panel.close(); - } - } + }; + LGraphCanvas.prototype.checkPanels = function () { + if (!this.canvas) return; + var panels = + this.canvas.parentNode.querySelectorAll(".litegraph.dialog"); + for (var i = 0; i < panels.length; ++i) { + var panel = panels[i]; + if (!panel.node) continue; + if (!panel.node.graph || panel.graph != this.graph) panel.close(); + } + }; - LGraphCanvas.onMenuNodeCollapse = function(value, options, e, menu, node) { - node.graph.beforeChange(/*?*/); - - var fApplyMultiNode = function(node){ - node.collapse(); - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - node.graph.afterChange(/*?*/); + LGraphCanvas.onMenuNodeCollapse = function (value, options, e, menu, node) { + node.graph.beforeChange(/*?*/); + + var fApplyMultiNode = function (node) { + node.collapse(); + }; + + var graphcanvas = LGraphCanvas.active_canvas; + if ( + !graphcanvas.selected_nodes || + Object.keys(graphcanvas.selected_nodes).length <= 1 + ) { + fApplyMultiNode(node); + } else { + for (var i in graphcanvas.selected_nodes) { + fApplyMultiNode(graphcanvas.selected_nodes[i]); + } + } + + node.graph.afterChange(/*?*/); }; - LGraphCanvas.onMenuNodePin = function(value, options, e, menu, node) { + LGraphCanvas.onMenuNodePin = function (value, options, e, menu, node) { node.pin(); }; - LGraphCanvas.onMenuNodeMode = function(value, options, e, menu, node) { - new LiteGraph.ContextMenu( - LiteGraph.NODE_MODES, - { event: e, callback: inner_clicked, parentMenu: menu, node: node } - ); + LGraphCanvas.onMenuNodeMode = function (value, options, e, menu, node) { + new LiteGraph.ContextMenu(LiteGraph.NODE_MODES, { + event: e, + callback: inner_clicked, + parentMenu: menu, + node: node, + }); function inner_clicked(v) { if (!node) { return; } var kV = Object.values(LiteGraph.NODE_MODES).indexOf(v); - var fApplyMultiNode = function(node){ - if (kV>=0 && LiteGraph.NODE_MODES[kV]) - node.changeMode(kV); - else{ - console.warn("unexpected mode: "+v); - node.changeMode(LiteGraph.ALWAYS); - } - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } + var fApplyMultiNode = function (node) { + if (kV >= 0 && LiteGraph.NODE_MODES[kV]) node.changeMode(kV); + else { + console.warn("unexpected mode: " + v); + node.changeMode(LiteGraph.ALWAYS); + } + }; + + var graphcanvas = LGraphCanvas.active_canvas; + if ( + !graphcanvas.selected_nodes || + Object.keys(graphcanvas.selected_nodes).length <= 1 + ) { + fApplyMultiNode(node); + } else { + for (var i in graphcanvas.selected_nodes) { + fApplyMultiNode(graphcanvas.selected_nodes[i]); + } + } } return false; }; - LGraphCanvas.onMenuNodeColors = function(value, options, e, menu, node) { + LGraphCanvas.onMenuNodeColors = function (value, options, e, menu, node) { if (!node) { throw "no node for color"; } @@ -12971,7 +14050,7 @@ LGraphNode.prototype.executeAction = function(action) values.push({ value: null, content: - "No color" + "No color", }); for (var i in LGraphCanvas.node_colors) { @@ -12985,7 +14064,7 @@ LGraphNode.prototype.executeAction = function(action) color.bgcolor + "'>" + i + - "" + "", }; values.push(value); } @@ -12993,7 +14072,7 @@ LGraphNode.prototype.executeAction = function(action) event: e, callback: inner_clicked, parentMenu: menu, - node: node + node: node, }); function inner_clicked(v) { @@ -13002,36 +14081,39 @@ LGraphNode.prototype.executeAction = function(action) } var color = v.value ? LGraphCanvas.node_colors[v.value] : null; - - var fApplyColor = function(node){ - if (color) { - if (node.constructor === LiteGraph.LGraphGroup) { - node.color = color.groupcolor; - } else { - node.color = color.color; - node.bgcolor = color.bgcolor; - } - } else { - delete node.color; - delete node.bgcolor; - } - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyColor(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyColor(graphcanvas.selected_nodes[i]); - } - } + + var fApplyColor = function (node) { + if (color) { + if (node.constructor === LiteGraph.LGraphGroup) { + node.color = color.groupcolor; + } else { + node.color = color.color; + node.bgcolor = color.bgcolor; + } + } else { + delete node.color; + delete node.bgcolor; + } + }; + + var graphcanvas = LGraphCanvas.active_canvas; + if ( + !graphcanvas.selected_nodes || + Object.keys(graphcanvas.selected_nodes).length <= 1 + ) { + fApplyColor(node); + } else { + for (var i in graphcanvas.selected_nodes) { + fApplyColor(graphcanvas.selected_nodes[i]); + } + } node.setDirtyCanvas(true, true); } return false; }; - LGraphCanvas.onMenuNodeShapes = function(value, options, e, menu, node) { + LGraphCanvas.onMenuNodeShapes = function (value, options, e, menu, node) { if (!node) { throw "no node passed"; } @@ -13040,117 +14122,130 @@ LGraphNode.prototype.executeAction = function(action) event: e, callback: inner_clicked, parentMenu: menu, - node: node + node: node, }); function inner_clicked(v) { if (!node) { return; } - node.graph.beforeChange(/*?*/); //node - - var fApplyMultiNode = function(node){ - node.shape = v; - } + node.graph.beforeChange(/*?*/); //node - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - node.graph.afterChange(/*?*/); //node + var fApplyMultiNode = function (node) { + node.shape = v; + }; + + var graphcanvas = LGraphCanvas.active_canvas; + if ( + !graphcanvas.selected_nodes || + Object.keys(graphcanvas.selected_nodes).length <= 1 + ) { + fApplyMultiNode(node); + } else { + for (var i in graphcanvas.selected_nodes) { + fApplyMultiNode(graphcanvas.selected_nodes[i]); + } + } + + node.graph.afterChange(/*?*/); //node node.setDirtyCanvas(true); } return false; }; - LGraphCanvas.onMenuNodeRemove = function(value, options, e, menu, node) { + LGraphCanvas.onMenuNodeRemove = function (value, options, e, menu, node) { if (!node) { throw "no node passed"; } - var graph = node.graph; - graph.beforeChange(); - - - var fApplyMultiNode = function(node){ - if (node.removable === false) { - return; - } - graph.remove(node); - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - graph.afterChange(); + var graph = node.graph; + graph.beforeChange(); + + var fApplyMultiNode = function (node) { + if (node.removable === false) { + return; + } + graph.remove(node); + }; + + var graphcanvas = LGraphCanvas.active_canvas; + if ( + !graphcanvas.selected_nodes || + Object.keys(graphcanvas.selected_nodes).length <= 1 + ) { + fApplyMultiNode(node); + } else { + for (var i in graphcanvas.selected_nodes) { + fApplyMultiNode(graphcanvas.selected_nodes[i]); + } + } + + graph.afterChange(); node.setDirtyCanvas(true, true); }; - LGraphCanvas.onMenuNodeToSubgraph = function(value, options, e, menu, node) { - var graph = node.graph; - var graphcanvas = LGraphCanvas.active_canvas; - if(!graphcanvas) //?? - return; + LGraphCanvas.onMenuNodeToSubgraph = function ( + value, + options, + e, + menu, + node + ) { + var graph = node.graph; + var graphcanvas = LGraphCanvas.active_canvas; + if (!graphcanvas) + //?? + return; - var nodes_list = Object.values( graphcanvas.selected_nodes || {} ); - if( !nodes_list.length ) - nodes_list = [ node ]; + var nodes_list = Object.values(graphcanvas.selected_nodes || {}); + if (!nodes_list.length) nodes_list = [node]; - var subgraph_node = LiteGraph.createNode("graph/subgraph"); - subgraph_node.pos = node.pos.concat(); - graph.add(subgraph_node); + var subgraph_node = LiteGraph.createNode("graph/subgraph"); + subgraph_node.pos = node.pos.concat(); + graph.add(subgraph_node); - subgraph_node.buildFromNodes( nodes_list ); + subgraph_node.buildFromNodes(nodes_list); - graphcanvas.deselectAllNodes(); + graphcanvas.deselectAllNodes(); node.setDirtyCanvas(true, true); }; - LGraphCanvas.onMenuNodeClone = function(value, options, e, menu, node) { - - node.graph.beforeChange(); - - var newSelected = {}; - - var fApplyMultiNode = function(node){ - if (node.clonable === false) { - return; - } - var newnode = node.clone(); - if (!newnode) { - return; - } - newnode.pos = [node.pos[0] + 5, node.pos[1] + 5]; - node.graph.add(newnode); - newSelected[newnode.id] = newnode; - } - - var graphcanvas = LGraphCanvas.active_canvas; - if (!graphcanvas.selected_nodes || Object.keys(graphcanvas.selected_nodes).length <= 1){ - fApplyMultiNode(node); - }else{ - for (var i in graphcanvas.selected_nodes) { - fApplyMultiNode(graphcanvas.selected_nodes[i]); - } - } - - if(Object.keys(newSelected).length){ - graphcanvas.selectNodes(newSelected); - } - - node.graph.afterChange(); + LGraphCanvas.onMenuNodeClone = function (value, options, e, menu, node) { + node.graph.beforeChange(); + + var newSelected = {}; + + var fApplyMultiNode = function (node) { + if (node.clonable === false) { + return; + } + var newnode = node.clone(); + if (!newnode) { + return; + } + newnode.pos = [node.pos[0] + 5, node.pos[1] + 5]; + node.graph.add(newnode); + newSelected[newnode.id] = newnode; + }; + + var graphcanvas = LGraphCanvas.active_canvas; + if ( + !graphcanvas.selected_nodes || + Object.keys(graphcanvas.selected_nodes).length <= 1 + ) { + fApplyMultiNode(node); + } else { + for (var i in graphcanvas.selected_nodes) { + fApplyMultiNode(graphcanvas.selected_nodes[i]); + } + } + + if (Object.keys(newSelected).length) { + graphcanvas.selectNodes(newSelected); + } + + node.graph.afterChange(); node.setDirtyCanvas(true, true); }; @@ -13163,17 +14258,17 @@ LGraphNode.prototype.executeAction = function(action) pale_blue: { color: "#2a363b", bgcolor: "#3f5159", - groupcolor: "#3f789e" + groupcolor: "#3f789e", }, cyan: { color: "#233", bgcolor: "#355", groupcolor: "#8AA" }, purple: { color: "#323", bgcolor: "#535", groupcolor: "#a1309b" }, yellow: { color: "#432", bgcolor: "#653", groupcolor: "#b58b2a" }, - black: { color: "#222", bgcolor: "#000", groupcolor: "#444" } + black: { color: "#222", bgcolor: "#000", groupcolor: "#444" }, }; - LGraphCanvas.prototype.getCanvasMenuOptions = function() { + LGraphCanvas.prototype.getCanvasMenuOptions = function () { var options = null; - var that = this; + var that = this; if (this.getMenuOptions) { options = this.getMenuOptions(); } else { @@ -13181,10 +14276,10 @@ LGraphNode.prototype.executeAction = function(action) { content: "Add Node", has_submenu: true, - callback: LGraphCanvas.onMenuAdd + callback: LGraphCanvas.onMenuAdd, }, { content: "Add Group", callback: LGraphCanvas.onGroupAdd }, - //{ content: "Arrange", callback: that.graph.arrange }, + //{ content: "Arrange", callback: that.graph.arrange }, //{content:"Collapse All", callback: LGraphCanvas.onMenuCollapseAll } ]; /*if (LiteGraph.showCanvasOptions){ @@ -13196,13 +14291,13 @@ LGraphNode.prototype.executeAction = function(action) content: "Align", has_submenu: true, callback: LGraphCanvas.onGroupAlign, - }) + }); } if (this._graph_stack && this._graph_stack.length > 0) { options.push(null, { content: "Close subgraph", - callback: this.closeSubgraph.bind(this) + callback: this.closeSubgraph.bind(this), }); } } @@ -13218,7 +14313,7 @@ LGraphNode.prototype.executeAction = function(action) }; //called by processContextMenu to extract the menu list - LGraphCanvas.prototype.getNodeMenuOptions = function(node) { + LGraphCanvas.prototype.getNodeMenuOptions = function (node) { var options = null; if (node.getMenuOptions) { @@ -13229,50 +14324,52 @@ LGraphNode.prototype.executeAction = function(action) content: "Inputs", has_submenu: true, disabled: true, - callback: LGraphCanvas.showMenuNodeOptionalInputs + callback: LGraphCanvas.showMenuNodeOptionalInputs, }, { content: "Outputs", has_submenu: true, disabled: true, - callback: LGraphCanvas.showMenuNodeOptionalOutputs + callback: LGraphCanvas.showMenuNodeOptionalOutputs, }, null, { content: "Properties", has_submenu: true, - callback: LGraphCanvas.onShowMenuNodeProperties + callback: LGraphCanvas.onShowMenuNodeProperties, }, null, { content: "Title", - callback: LGraphCanvas.onShowPropertyEditor + callback: LGraphCanvas.onShowPropertyEditor, }, { content: "Mode", has_submenu: true, - callback: LGraphCanvas.onMenuNodeMode - }]; - if(node.resizable !== false){ + callback: LGraphCanvas.onMenuNodeMode, + }, + ]; + if (node.resizable !== false) { options.push({ - content: "Resize", callback: LGraphCanvas.onMenuResizeNode + content: "Resize", + callback: LGraphCanvas.onMenuResizeNode, }); } options.push( { content: "Collapse", - callback: LGraphCanvas.onMenuNodeCollapse + callback: LGraphCanvas.onMenuNodeCollapse, }, { content: "Pin", callback: LGraphCanvas.onMenuNodePin }, { content: "Colors", has_submenu: true, - callback: LGraphCanvas.onMenuNodeColors + callback: LGraphCanvas.onMenuNodeColors, }, { content: "Shapes", has_submenu: true, - callback: LGraphCanvas.onMenuNodeShapes + callback: LGraphCanvas.onMenuNodeShapes, }, null ); @@ -13303,29 +14400,30 @@ LGraphNode.prototype.executeAction = function(action) if (node.clonable !== false) { options.push({ content: "Clone", - callback: LGraphCanvas.onMenuNodeClone + callback: LGraphCanvas.onMenuNodeClone, }); } - if(0) //TODO - options.push({ - content: "To Subgraph", - callback: LGraphCanvas.onMenuNodeToSubgraph - }); + if (0) + //TODO + options.push({ + content: "To Subgraph", + callback: LGraphCanvas.onMenuNodeToSubgraph, + }); if (Object.keys(this.selected_nodes).length > 1) { options.push({ content: "Align Selected To", has_submenu: true, callback: LGraphCanvas.onNodeAlign, - }) + }); } - options.push(null, { - content: "Remove", - disabled: !(node.removable !== false && !node.block_delete ), - callback: LGraphCanvas.onMenuNodeRemove - }); + options.push(null, { + content: "Remove", + disabled: !(node.removable !== false && !node.block_delete), + callback: LGraphCanvas.onMenuNodeRemove, + }); if (node.graph && node.graph.onGetNodeMenuOptions) { node.graph.onGetNodeMenuOptions(options, node); @@ -13334,28 +14432,28 @@ LGraphNode.prototype.executeAction = function(action) return options; }; - LGraphCanvas.prototype.getGroupMenuOptions = function(node) { + LGraphCanvas.prototype.getGroupMenuOptions = function (node) { var o = [ { content: "Title", callback: LGraphCanvas.onShowPropertyEditor }, { content: "Color", has_submenu: true, - callback: LGraphCanvas.onMenuNodeColors + callback: LGraphCanvas.onMenuNodeColors, }, { content: "Font size", property: "font_size", type: "Number", - callback: LGraphCanvas.onShowPropertyEditor + callback: LGraphCanvas.onShowPropertyEditor, }, null, - { content: "Remove", callback: LGraphCanvas.onMenuNodeRemove } + { content: "Remove", callback: LGraphCanvas.onMenuNodeRemove }, ]; return o; }; - LGraphCanvas.prototype.processContextMenu = function(node, event) { + LGraphCanvas.prototype.processContextMenu = function (node, event) { var that = this; var canvas = LGraphCanvas.active_canvas; var ref_window = canvas.getCanvasWindow(); @@ -13364,11 +14462,10 @@ LGraphNode.prototype.executeAction = function(action) var options = { event: event, callback: inner_option_clicked, - extra: node + extra: node, }; - if(node) - options.title = node.type; + if (node) options.title = node.type; //check if mouse is in input var slot = null; @@ -13392,17 +14489,16 @@ LGraphNode.prototype.executeAction = function(action) menu_info.push({ content: "Disconnect Links", slot: slot }); } var _slot = slot.input || slot.output; - if (_slot.removable){ - menu_info.push( - _slot.locked - ? "Cannot remove" - : { content: "Remove Slot", slot: slot } - ); - } - if (!_slot.nameLocked){ - menu_info.push({ content: "Rename Slot", slot: slot }); - } - + if (_slot.removable) { + menu_info.push( + _slot.locked + ? "Cannot remove" + : { content: "Remove Slot", slot: slot } + ); + } + if (!_slot.nameLocked) { + menu_info.push({ content: "Rename Slot", slot: slot }); + } } options.title = (slot.input ? slot.input.type : slot.output.type) || "*"; @@ -13430,8 +14526,8 @@ LGraphNode.prototype.executeAction = function(action) submenu: { title: "Group", extra: group, - options: this.getGroupMenuOptions(group) - } + options: this.getGroupMenuOptions(group), + }, }); } } @@ -13482,8 +14578,8 @@ LGraphNode.prototype.executeAction = function(action) if (input && slot_info) { input.value = slot_info.label || ""; } - var inner = function(){ - node.graph.beforeChange(); + var inner = function () { + node.graph.beforeChange(); if (input.value) { if (slot_info) { slot_info.label = input.value; @@ -13492,16 +14588,19 @@ LGraphNode.prototype.executeAction = function(action) } dialog.close(); node.graph.afterChange(); - } + }; dialog.querySelector("button").addEventListener("click", inner); - input.addEventListener("keydown", function(e) { + input.addEventListener("keydown", function (e) { dialog.is_modified = true; if (e.keyCode == 27) { //ESC dialog.close(); } else if (e.keyCode == 13) { inner(); // save - } else if (e.keyCode != 13 && e.target.localName != "textarea") { + } else if ( + e.keyCode != 13 && + e.target.localName != "textarea" + ) { return; } e.preventDefault(); @@ -13678,18 +14777,29 @@ LGraphNode.prototype.executeAction = function(action) } } - var eventClass = null; - if(options.event) //use strings because comparing classes between windows doesnt work - eventClass = options.event.constructor.name; - if ( eventClass !== "MouseEvent" && + var eventClass = null; + if (options.event) + //use strings because comparing classes between windows doesnt work + eventClass = options.event.constructor.name; + if ( + eventClass !== "MouseEvent" && eventClass !== "CustomEvent" && - eventClass !== "PointerEvent" + eventClass !== "PointerEvent" ) { console.error( - "Event passed to ContextMenu is not of type MouseEvent or CustomEvent. Ignoring it. ("+eventClass+")" + "Event passed to ContextMenu is not of type MouseEvent or CustomEvent. Ignoring it. (" + + eventClass + + ")" ); options.event = null; } + var elements = document.getElementsByClassName( + "litemenubar-panel dark" + ); + + while (elements.length > 0) { + elements[0].parentNode.removeChild(elements[0]); + } var root = document.createElement("div"); root.className = "litegraph litecontextmenu litemenubar-panel"; @@ -13699,14 +14809,16 @@ LGraphNode.prototype.executeAction = function(action) root.style.minWidth = 100; root.style.minHeight = 100; root.style.pointerEvents = "none"; - setTimeout(function() { + setTimeout(function () { root.style.pointerEvents = "auto"; }, 100); //delay so the mouse up event is not caught by this element //this prevents the default context browser menu to open in case this menu was created when pressing right button - LiteGraph.pointerListenerAdd(root,"up", - function(e) { - //console.log("pointerevents: ContextMenu up root prevent"); + LiteGraph.pointerListenerAdd( + root, + "up", + function (e) { + //console.log("pointerevents: ContextMenu up root prevent"); e.preventDefault(); return true; }, @@ -13714,7 +14826,7 @@ LGraphNode.prototype.executeAction = function(action) ); root.addEventListener( "contextmenu", - function(e) { + function (e) { if (e.button != 2) { //right button return false; @@ -13725,9 +14837,11 @@ LGraphNode.prototype.executeAction = function(action) true ); - LiteGraph.pointerListenerAdd(root,"down", - function(e) { - //console.log("pointerevents: ContextMenu down"); + LiteGraph.pointerListenerAdd( + root, + "down", + function (e) { + //console.log("pointerevents: ContextMenu down"); if (e.button == 2) { that.close(); e.preventDefault(); @@ -13764,7 +14878,7 @@ LGraphNode.prototype.executeAction = function(action) //entries var num = 0; - for (var i=0; i < values.length; i++) { + for (var i = 0; i < values.length; i++) { var name = values.constructor == Array ? values[i] : i; if (name != null && name.constructor !== String) { name = name.content === undefined ? String(name) : name.content; @@ -13787,8 +14901,8 @@ LGraphNode.prototype.executeAction = function(action) //that.close(e); });*/ - LiteGraph.pointerListenerAdd(root,"enter", function(e) { - //console.log("pointerevents: ContextMenu enter"); + LiteGraph.pointerListenerAdd(root, "enter", function (e) { + //console.log("pointerevents: ContextMenu enter"); if (root.closing_timer) { clearTimeout(root.closing_timer); } @@ -13804,10 +14918,9 @@ LGraphNode.prototype.executeAction = function(action) root_document = document; } - if( root_document.fullscreenElement ) - root_document.fullscreenElement.appendChild(root); - else - root_document.body.appendChild(root); + if (root_document.fullscreenElement) + root_document.fullscreenElement.appendChild(root); + else root_document.body.appendChild(root); //compute best position var left = options.left || 0; @@ -13826,13 +14939,21 @@ LGraphNode.prototype.executeAction = function(action) var body_rect = document.body.getBoundingClientRect(); var root_rect = root.getBoundingClientRect(); - if(body_rect.height == 0) - console.error("document.body height is 0. That is dangerous, set html,body { height: 100%; }"); + if (body_rect.height == 0) + console.error( + "document.body height is 0. That is dangerous, set html,body { height: 100%; }" + ); - if (body_rect.width && left > body_rect.width - root_rect.width - 10) { + if ( + body_rect.width && + left > body_rect.width - root_rect.width - 10 + ) { left = body_rect.width - root_rect.width - 10; } - if (body_rect.height && top > body_rect.height - root_rect.height - 10) { + if ( + body_rect.height && + top > body_rect.height - root_rect.height - 10 + ) { top = body_rect.height - root_rect.height - 10; } } @@ -13845,7 +14966,7 @@ LGraphNode.prototype.executeAction = function(action) } } - ContextMenu.prototype.addItem = function(name, value, options) { + ContextMenu.prototype.addItem = function (name, value, options) { var that = this; options = options || {}; @@ -13889,7 +15010,7 @@ LGraphNode.prototype.executeAction = function(action) element.addEventListener("click", inner_onclick); } if (!disabled && options.autoopen) { - LiteGraph.pointerListenerAdd(element,"enter",inner_over); + LiteGraph.pointerListenerAdd(element, "enter", inner_over); } function inner_over(e) { @@ -13957,7 +15078,7 @@ LGraphNode.prototype.executeAction = function(action) value.submenu.ignore_item_callbacks, title: value.submenu.title, extra: value.submenu.extra, - autoopen: options.autoopen + autoopen: options.autoopen, }); close_parent = false; } @@ -13971,7 +15092,7 @@ LGraphNode.prototype.executeAction = function(action) return element; }; - ContextMenu.prototype.close = function(e, ignore_parent_menu) { + ContextMenu.prototype.close = function (e, ignore_parent_menu) { if (this.root.parentNode) { this.root.parentNode.removeChild(this.root); } @@ -13984,7 +15105,11 @@ LGraphNode.prototype.executeAction = function(action) e && !ContextMenu.isCursorOverElement(e, this.parentMenu.root) ) { - ContextMenu.trigger(this.parentMenu.root, LiteGraph.pointerevents_method+"leave", e); + ContextMenu.trigger( + this.parentMenu.root, + LiteGraph.pointerevents_method + "leave", + e + ); } } if (this.current_submenu) { @@ -13994,13 +15119,13 @@ LGraphNode.prototype.executeAction = function(action) if (this.root.closing_timer) { clearTimeout(this.root.closing_timer); } - + // TODO implement : LiteGraph.contextMenuClosed(); :: keep track of opened / closed / current ContextMenu // on key press, allow filtering/selecting the context menu elements }; //this code is used to trigger events easily (used in the context menu mouseleave - ContextMenu.trigger = function(element, event_name, params, origin) { + ContextMenu.trigger = function (element, event_name, params, origin) { var evt = document.createEvent("CustomEvent"); evt.initCustomEvent(event_name, true, true, params); //canBubble, cancelable, detail evt.srcElement = origin; @@ -14014,21 +15139,21 @@ LGraphNode.prototype.executeAction = function(action) }; //returns the top most menu - ContextMenu.prototype.getTopMenu = function() { + ContextMenu.prototype.getTopMenu = function () { if (this.options.parentMenu) { return this.options.parentMenu.getTopMenu(); } return this; }; - ContextMenu.prototype.getFirstEvent = function() { + ContextMenu.prototype.getFirstEvent = function () { if (this.options.parentMenu) { return this.options.parentMenu.getFirstEvent(); } return this.options.event; }; - ContextMenu.isCursorOverElement = function(event, element) { + ContextMenu.isCursorOverElement = function (event, element) { var left = event.clientX; var top = event.clientY; var rect = element.getBoundingClientRect(); @@ -14048,7 +15173,7 @@ LGraphNode.prototype.executeAction = function(action) LiteGraph.ContextMenu = ContextMenu; - LiteGraph.closeAllContextMenus = function(ref_window) { + LiteGraph.closeAllContextMenus = function (ref_window) { ref_window = ref_window || window; var elements = ref_window.document.querySelectorAll(".litecontextmenu"); @@ -14061,7 +15186,7 @@ LGraphNode.prototype.executeAction = function(action) result.push(elements[i]); } - for (var i=0; i < result.length; i++) { + for (var i = 0; i < result.length; i++) { if (result[i].close) { result[i].close(); } else if (result[i].parentNode) { @@ -14070,7 +15195,7 @@ LGraphNode.prototype.executeAction = function(action) } }; - LiteGraph.extendClass = function(target, origin) { + LiteGraph.extendClass = function (target, origin) { for (var i in origin) { //copy class properties if (target.hasOwnProperty(i)) { @@ -14113,186 +15238,180 @@ LGraphNode.prototype.executeAction = function(action) } }; - //used by some widgets to render a curve editor - function CurveEditor( points ) - { - this.points = points; - this.selected = -1; - this.nearest = -1; - this.size = null; //stores last size used - this.must_update = true; - this.margin = 5; - } + //used by some widgets to render a curve editor + function CurveEditor(points) { + this.points = points; + this.selected = -1; + this.nearest = -1; + this.size = null; //stores last size used + this.must_update = true; + this.margin = 5; + } - CurveEditor.sampleCurve = function(f,points) - { - if(!points) - return; - for(var i = 0; i < points.length - 1; ++i) - { - var p = points[i]; - var pn = points[i+1]; - if(pn[0] < f) - continue; - var r = (pn[0] - p[0]); - if( Math.abs(r) < 0.00001 ) - return p[1]; - var local_f = (f - p[0]) / r; - return p[1] * (1.0 - local_f) + pn[1] * local_f; - } - return 0; - } + CurveEditor.sampleCurve = function (f, points) { + if (!points) return; + for (var i = 0; i < points.length - 1; ++i) { + var p = points[i]; + var pn = points[i + 1]; + if (pn[0] < f) continue; + var r = pn[0] - p[0]; + if (Math.abs(r) < 0.00001) return p[1]; + var local_f = (f - p[0]) / r; + return p[1] * (1.0 - local_f) + pn[1] * local_f; + } + return 0; + }; - CurveEditor.prototype.draw = function( ctx, size, graphcanvas, background_color, line_color, inactive ) - { - var points = this.points; - if(!points) - return; - this.size = size; - var w = size[0] - this.margin * 2; - var h = size[1] - this.margin * 2; - - line_color = line_color || "#666"; - - ctx.save(); - ctx.translate(this.margin,this.margin); - - if(background_color) - { - ctx.fillStyle = "#111"; - ctx.fillRect(0,0,w,h); - ctx.fillStyle = "#222"; - ctx.fillRect(w*0.5,0,1,h); - ctx.strokeStyle = "#333"; - ctx.strokeRect(0,0,w,h); - } - ctx.strokeStyle = line_color; - if(inactive) - ctx.globalAlpha = 0.5; - ctx.beginPath(); - for(var i = 0; i < points.length; ++i) - { - var p = points[i]; - ctx.lineTo( p[0] * w, (1.0 - p[1]) * h ); - } - ctx.stroke(); - ctx.globalAlpha = 1; - if(!inactive) - for(var i = 0; i < points.length; ++i) - { - var p = points[i]; - ctx.fillStyle = this.selected == i ? "#FFF" : (this.nearest == i ? "#DDD" : "#AAA"); - ctx.beginPath(); - ctx.arc( p[0] * w, (1.0 - p[1]) * h, 2, 0, Math.PI * 2 ); - ctx.fill(); - } - ctx.restore(); - } + CurveEditor.prototype.draw = function ( + ctx, + size, + graphcanvas, + background_color, + line_color, + inactive + ) { + var points = this.points; + if (!points) return; + this.size = size; + var w = size[0] - this.margin * 2; + var h = size[1] - this.margin * 2; - //localpos is mouse in curve editor space - CurveEditor.prototype.onMouseDown = function( localpos, graphcanvas ) - { - var points = this.points; - if(!points) - return; - if( localpos[1] < 0 ) - return; - - //this.captureInput(true); - var w = this.size[0] - this.margin * 2; - var h = this.size[1] - this.margin * 2; - var x = localpos[0] - this.margin; - var y = localpos[1] - this.margin; - var pos = [x,y]; - var max_dist = 30 / graphcanvas.ds.scale; - //search closer one - this.selected = this.getCloserPoint(pos, max_dist); - //create one - if(this.selected == -1) - { - var point = [x / w, 1 - y / h]; - points.push(point); - points.sort(function(a,b){ return a[0] - b[0]; }); - this.selected = points.indexOf(point); - this.must_update = true; - } - if(this.selected != -1) - return true; - } + line_color = line_color || "#666"; - CurveEditor.prototype.onMouseMove = function( localpos, graphcanvas ) - { - var points = this.points; - if(!points) - return; - var s = this.selected; - if(s < 0) - return; - var x = (localpos[0] - this.margin) / (this.size[0] - this.margin * 2 ); - var y = (localpos[1] - this.margin) / (this.size[1] - this.margin * 2 ); - var curvepos = [(localpos[0] - this.margin),(localpos[1] - this.margin)]; - var max_dist = 30 / graphcanvas.ds.scale; - this._nearest = this.getCloserPoint(curvepos, max_dist); - var point = points[s]; - if(point) - { - var is_edge_point = s == 0 || s == points.length - 1; - if( !is_edge_point && (localpos[0] < -10 || localpos[0] > this.size[0] + 10 || localpos[1] < -10 || localpos[1] > this.size[1] + 10) ) - { - points.splice(s,1); - this.selected = -1; - return; - } - if( !is_edge_point ) //not edges - point[0] = clamp(x, 0, 1); - else - point[0] = s == 0 ? 0 : 1; - point[1] = 1.0 - clamp(y, 0, 1); - points.sort(function(a,b){ return a[0] - b[0]; }); - this.selected = points.indexOf(point); - this.must_update = true; - } - } + ctx.save(); + ctx.translate(this.margin, this.margin); - CurveEditor.prototype.onMouseUp = function( localpos, graphcanvas ) - { - this.selected = -1; - return false; - } + if (background_color) { + ctx.fillStyle = "#111"; + ctx.fillRect(0, 0, w, h); + ctx.fillStyle = "#222"; + ctx.fillRect(w * 0.5, 0, 1, h); + ctx.strokeStyle = "#333"; + ctx.strokeRect(0, 0, w, h); + } + ctx.strokeStyle = line_color; + if (inactive) ctx.globalAlpha = 0.5; + ctx.beginPath(); + for (var i = 0; i < points.length; ++i) { + var p = points[i]; + ctx.lineTo(p[0] * w, (1.0 - p[1]) * h); + } + ctx.stroke(); + ctx.globalAlpha = 1; + if (!inactive) + for (var i = 0; i < points.length; ++i) { + var p = points[i]; + ctx.fillStyle = + this.selected == i + ? "#FFF" + : this.nearest == i + ? "#DDD" + : "#AAA"; + ctx.beginPath(); + ctx.arc(p[0] * w, (1.0 - p[1]) * h, 2, 0, Math.PI * 2); + ctx.fill(); + } + ctx.restore(); + }; - CurveEditor.prototype.getCloserPoint = function(pos, max_dist) - { - var points = this.points; - if(!points) - return -1; - max_dist = max_dist || 30; - var w = (this.size[0] - this.margin * 2); - var h = (this.size[1] - this.margin * 2); - var num = points.length; - var p2 = [0,0]; - var min_dist = 1000000; - var closest = -1; - var last_valid = -1; - for(var i = 0; i < num; ++i) - { - var p = points[i]; - p2[0] = p[0] * w; - p2[1] = (1.0 - p[1]) * h; - if(p2[0] < pos[0]) - last_valid = i; - var dist = vec2.distance(pos,p2); - if(dist > min_dist || dist > max_dist) - continue; - closest = i; - min_dist = dist; - } - return closest; - } + //localpos is mouse in curve editor space + CurveEditor.prototype.onMouseDown = function (localpos, graphcanvas) { + var points = this.points; + if (!points) return; + if (localpos[1] < 0) return; + + //this.captureInput(true); + var w = this.size[0] - this.margin * 2; + var h = this.size[1] - this.margin * 2; + var x = localpos[0] - this.margin; + var y = localpos[1] - this.margin; + var pos = [x, y]; + var max_dist = 30 / graphcanvas.ds.scale; + //search closer one + this.selected = this.getCloserPoint(pos, max_dist); + //create one + if (this.selected == -1) { + var point = [x / w, 1 - y / h]; + points.push(point); + points.sort(function (a, b) { + return a[0] - b[0]; + }); + this.selected = points.indexOf(point); + this.must_update = true; + } + if (this.selected != -1) return true; + }; + + CurveEditor.prototype.onMouseMove = function (localpos, graphcanvas) { + var points = this.points; + if (!points) return; + var s = this.selected; + if (s < 0) return; + var x = (localpos[0] - this.margin) / (this.size[0] - this.margin * 2); + var y = (localpos[1] - this.margin) / (this.size[1] - this.margin * 2); + var curvepos = [localpos[0] - this.margin, localpos[1] - this.margin]; + var max_dist = 30 / graphcanvas.ds.scale; + this._nearest = this.getCloserPoint(curvepos, max_dist); + var point = points[s]; + if (point) { + var is_edge_point = s == 0 || s == points.length - 1; + if ( + !is_edge_point && + (localpos[0] < -10 || + localpos[0] > this.size[0] + 10 || + localpos[1] < -10 || + localpos[1] > this.size[1] + 10) + ) { + points.splice(s, 1); + this.selected = -1; + return; + } + if (!is_edge_point) + //not edges + point[0] = clamp(x, 0, 1); + else point[0] = s == 0 ? 0 : 1; + point[1] = 1.0 - clamp(y, 0, 1); + points.sort(function (a, b) { + return a[0] - b[0]; + }); + this.selected = points.indexOf(point); + this.must_update = true; + } + }; + + CurveEditor.prototype.onMouseUp = function (localpos, graphcanvas) { + this.selected = -1; + return false; + }; - LiteGraph.CurveEditor = CurveEditor; + CurveEditor.prototype.getCloserPoint = function (pos, max_dist) { + var points = this.points; + if (!points) return -1; + max_dist = max_dist || 30; + var w = this.size[0] - this.margin * 2; + var h = this.size[1] - this.margin * 2; + var num = points.length; + var p2 = [0, 0]; + var min_dist = 1000000; + var closest = -1; + var last_valid = -1; + for (var i = 0; i < num; ++i) { + var p = points[i]; + p2[0] = p[0] * w; + p2[1] = (1.0 - p[1]) * h; + if (p2[0] < pos[0]) last_valid = i; + var dist = vec2.distance(pos, p2); + if (dist > min_dist || dist > max_dist) continue; + closest = i; + min_dist = dist; + } + return closest; + }; + + LiteGraph.CurveEditor = CurveEditor; //used to create nodes from wrapping functions - LiteGraph.getParameterNames = function(func) { + LiteGraph.getParameterNames = function (func) { return (func + "") .replace(/[/][/].*$/gm, "") // strip single-line comments .replace(/\s+/g, "") // strip white space @@ -14304,108 +15423,163 @@ LGraphNode.prototype.executeAction = function(action) .filter(Boolean); // split & filter [""] }; - /* helper for interaction: pointer, touch, mouse Listeners + /* helper for interaction: pointer, touch, mouse Listeners used by LGraphCanvas DragAndScale ContextMenu*/ - LiteGraph.pointerListenerAdd = function(oDOM, sEvIn, fCall, capture=false) { - if (!oDOM || !oDOM.addEventListener || !sEvIn || typeof fCall!=="function"){ - //console.log("cant pointerListenerAdd "+oDOM+", "+sEvent+", "+fCall); - return; // -- break -- - } - - var sMethod = LiteGraph.pointerevents_method; - var sEvent = sEvIn; - - // UNDER CONSTRUCTION - // convert pointerevents to touch event when not available - if (sMethod=="pointer" && !window.PointerEvent){ - console.warn("sMethod=='pointer' && !window.PointerEvent"); - console.log("Converting pointer["+sEvent+"] : down move up cancel enter TO touchstart touchmove touchend, etc .."); - switch(sEvent){ - case "down":{ - sMethod = "touch"; - sEvent = "start"; - break; - } - case "move":{ - sMethod = "touch"; - //sEvent = "move"; - break; - } - case "up":{ - sMethod = "touch"; - sEvent = "end"; - break; - } - case "cancel":{ - sMethod = "touch"; - //sEvent = "cancel"; - break; - } - case "enter":{ - console.log("debug: Should I send a move event?"); // ??? - break; - } - // case "over": case "out": not used at now - default:{ - console.warn("PointerEvent not available in this browser ? The event "+sEvent+" would not be called"); - } - } - } + LiteGraph.pointerListenerAdd = function ( + oDOM, + sEvIn, + fCall, + capture = false + ) { + if ( + !oDOM || + !oDOM.addEventListener || + !sEvIn || + typeof fCall !== "function" + ) { + //console.log("cant pointerListenerAdd "+oDOM+", "+sEvent+", "+fCall); + return; // -- break -- + } - switch(sEvent){ - //both pointer and move events - case "down": case "up": case "move": case "over": case "out": case "enter": - { - oDOM.addEventListener(sMethod+sEvent, fCall, capture); - } - // only pointerevents - case "leave": case "cancel": case "gotpointercapture": case "lostpointercapture": - { - if (sMethod!="mouse"){ - return oDOM.addEventListener(sMethod+sEvent, fCall, capture); - } - } - // not "pointer" || "mouse" - default: - return oDOM.addEventListener(sEvent, fCall, capture); - } - } - LiteGraph.pointerListenerRemove = function(oDOM, sEvent, fCall, capture=false) { - if (!oDOM || !oDOM.removeEventListener || !sEvent || typeof fCall!=="function"){ - //console.log("cant pointerListenerRemove "+oDOM+", "+sEvent+", "+fCall); - return; // -- break -- - } - switch(sEvent){ - //both pointer and move events - case "down": case "up": case "move": case "over": case "out": case "enter": - { - if (LiteGraph.pointerevents_method=="pointer" || LiteGraph.pointerevents_method=="mouse"){ - oDOM.removeEventListener(LiteGraph.pointerevents_method+sEvent, fCall, capture); - } - } - // only pointerevents - case "leave": case "cancel": case "gotpointercapture": case "lostpointercapture": - { - if (LiteGraph.pointerevents_method=="pointer"){ - return oDOM.removeEventListener(LiteGraph.pointerevents_method+sEvent, fCall, capture); - } - } - // not "pointer" || "mouse" - default: - return oDOM.removeEventListener(sEvent, fCall, capture); - } - } + var sMethod = LiteGraph.pointerevents_method; + var sEvent = sEvIn; + + // UNDER CONSTRUCTION + // convert pointerevents to touch event when not available + if (sMethod == "pointer" && !window.PointerEvent) { + console.warn("sMethod=='pointer' && !window.PointerEvent"); + console.log( + "Converting pointer[" + + sEvent + + "] : down move up cancel enter TO touchstart touchmove touchend, etc .." + ); + switch (sEvent) { + case "down": { + sMethod = "touch"; + sEvent = "start"; + break; + } + case "move": { + sMethod = "touch"; + //sEvent = "move"; + break; + } + case "up": { + sMethod = "touch"; + sEvent = "end"; + break; + } + case "cancel": { + sMethod = "touch"; + //sEvent = "cancel"; + break; + } + case "enter": { + console.log("debug: Should I send a move event?"); // ??? + break; + } + // case "over": case "out": not used at now + default: { + console.warn( + "PointerEvent not available in this browser ? The event " + + sEvent + + " would not be called" + ); + } + } + } + + switch (sEvent) { + //both pointer and move events + case "down": + case "up": + case "move": + case "over": + case "out": + case "enter": { + oDOM.addEventListener(sMethod + sEvent, fCall, capture); + } + // only pointerevents + case "leave": + case "cancel": + case "gotpointercapture": + case "lostpointercapture": { + if (sMethod != "mouse") { + return oDOM.addEventListener( + sMethod + sEvent, + fCall, + capture + ); + } + } + // not "pointer" || "mouse" + default: + return oDOM.addEventListener(sEvent, fCall, capture); + } + }; + LiteGraph.pointerListenerRemove = function ( + oDOM, + sEvent, + fCall, + capture = false + ) { + if ( + !oDOM || + !oDOM.removeEventListener || + !sEvent || + typeof fCall !== "function" + ) { + //console.log("cant pointerListenerRemove "+oDOM+", "+sEvent+", "+fCall); + return; // -- break -- + } + switch (sEvent) { + //both pointer and move events + case "down": + case "up": + case "move": + case "over": + case "out": + case "enter": { + if ( + LiteGraph.pointerevents_method == "pointer" || + LiteGraph.pointerevents_method == "mouse" + ) { + oDOM.removeEventListener( + LiteGraph.pointerevents_method + sEvent, + fCall, + capture + ); + } + } + // only pointerevents + case "leave": + case "cancel": + case "gotpointercapture": + case "lostpointercapture": { + if (LiteGraph.pointerevents_method == "pointer") { + return oDOM.removeEventListener( + LiteGraph.pointerevents_method + sEvent, + fCall, + capture + ); + } + } + // not "pointer" || "mouse" + default: + return oDOM.removeEventListener(sEvent, fCall, capture); + } + }; function clamp(v, a, b) { return a > v ? a : b < v ? b : v; - }; + } global.clamp = clamp; if (typeof window != "undefined" && !window["requestAnimationFrame"]) { window.requestAnimationFrame = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || - function(callback) { + function (callback) { window.setTimeout(callback, 1000 / 60); }; } @@ -14421,4 +15595,3 @@ if (typeof exports != "undefined") { exports.LGraphCanvas = this.LGraphCanvas; exports.ContextMenu = this.ContextMenu; } -