redone GUI system for nodes

This commit is contained in:
tamat
2018-07-24 19:57:04 +02:00
parent 41059286e4
commit e032e4748c
5 changed files with 991 additions and 869 deletions

View File

@@ -26,6 +26,7 @@ var LiteGraph = global.LiteGraph = {
NODE_TITLE_HEIGHT: 20,
NODE_SLOT_HEIGHT: 15,
NODE_WIDGET_HEIGHT: 20,
NODE_WIDTH: 140,
NODE_MIN_WIDTH: 50,
NODE_COLLAPSED_RADIUS: 10,
@@ -37,17 +38,18 @@ var LiteGraph = global.LiteGraph = {
NODE_SUBTEXT_SIZE: 12,
NODE_DEFAULT_COLOR: "#333",
NODE_DEFAULT_BGCOLOR: "#444",
NODE_DEFAULT_BOXCOLOR: "#CCC",
NODE_DEFAULT_BOXCOLOR: "#888",
NODE_DEFAULT_SHAPE: "box",
MAX_NUMBER_OF_NODES: 1000, //avoid infinite loops
DEFAULT_POSITION: [100,100],//default node position
node_images_path: "",
VALID_SHAPES: ["box","round"], //,"circle"
VALID_SHAPES: ["default","box","round","card"], //,"circle"
BOX_SHAPE: 1,
ROUND_SHAPE: 2,
CIRCLE_SHAPE: 3,
CARD_SHAPE: 4,
//enums
INPUT: 1,
@@ -106,9 +108,11 @@ var LiteGraph = global.LiteGraph = {
set: function(v) {
switch(v)
{
case "default": delete this._shape; break;
case "box": this._shape = LiteGraph.BOX_SHAPE; break;
case "round": this._shape = LiteGraph.ROUND_SHAPE; break;
case "circle": this._shape = LiteGraph.CIRCLE_SHAPE; break;
case "card": this._shape = LiteGraph.CARD_SHAPE; break;
default:
this._shape = v;
}
@@ -246,17 +250,23 @@ var LiteGraph = global.LiteGraph = {
* @return {Array} array with all the node classes
*/
getNodeTypesInCategory: function(category)
getNodeTypesInCategory: function( category, filter )
{
var r = [];
for(var i in this.registered_node_types)
if(category == "")
{
var type = this.registered_node_types[i];
if(filter && type.filter && type.filter != filter)
continue;
if(category == "" )
{
if (this.registered_node_types[i].category == null)
r.push(this.registered_node_types[i]);
if (type.category == null)
r.push(type);
}
else if (this.registered_node_types[i].category == category)
r.push(this.registered_node_types[i]);
else if (type.category == category)
r.push(type);
}
return r;
},
@@ -1580,9 +1590,10 @@ LGraph.prototype.onNodeTrace = function(node, msg, color)
flags:
+ skip_title_render
+ clip_area
+ clip_area: if you render outside the node, it will be cliped
+ unsafe_execution: not allowed for safe execution
+ skip_repeated_outputs: when adding new outputs, it wont show if there is one already connected
+ resizable: if set to false it wont be resizable with the mouse
supported callbacks:
+ onAdded: when added to graph
@@ -1659,10 +1670,7 @@ LGraphNode.prototype._ctor = function( title )
this.properties_info = []; //for the info
this.data = null; //persistent local data
this.flags = {
//skip_title_render: true,
//unsafe_execution: false,
};
this.flags = {};
}
/**
@@ -1787,10 +1795,10 @@ LGraphNode.prototype.serialize = function()
mode: this.mode
};
if(this.inputs)
if( this.inputs )
o.inputs = this.inputs;
if(this.outputs)
if( this.outputs )
{
//clear outputs last data (because data in connections is never serialized but stored inside the outputs info)
for(var i = 0; i < this.outputs.length; i++)
@@ -1801,19 +1809,19 @@ LGraphNode.prototype.serialize = function()
if( this.title && this.title != this.constructor.title )
o.title = this.title;
if(this.properties)
o.properties = LiteGraph.cloneObject(this.properties);
if( this.properties )
o.properties = LiteGraph.cloneObject( this.properties );
if(!o.type)
if( !o.type )
o.type = this.constructor.type;
if(this.color)
if( this.color )
o.color = this.color;
if(this.bgcolor)
if( this.bgcolor )
o.bgcolor = this.bgcolor;
if(this.boxcolor)
if( this.boxcolor )
o.boxcolor = this.boxcolor;
if(this.shape)
if( this.shape )
o.shape = this.shape;
if(this.onSerialize)
@@ -2388,7 +2396,7 @@ LGraphNode.prototype.computeSize = function( minHeight, out )
var size = out || new Float32Array([0,0]);
rows = Math.max(rows, 1);
var font_size = LiteGraph.NODE_TEXT_SIZE; //although it should be graphcanvas.inner_text_font size
size[1] = rows * (font_size + 1) + 4;
size[1] = rows * (font_size + 1) + ( this.widgets ? this.widgets.length : 0 ) * (LiteGraph.NODE_WIDGET_HEIGHT + 4 ) + 4;
var font_size = font_size;
var title_width = compute_text_size( this.title );
@@ -2431,6 +2439,22 @@ LGraphNode.prototype.computeSize = function( minHeight, out )
return size;
}
LGraphNode.prototype.addWidget = function( type, name, value, callback, options )
{
if(!this.widgets)
this.widgets = [];
var w = {
type: type,
name: name,
value: value,
callback: callback,
options: options
};
this.widgets.push(w);
return w;
}
/**
* returns the bounding of the object, used for rendering purposes
* bounding is: [topleft_cornerx, topleft_cornery, width, height]
@@ -3025,6 +3049,7 @@ function LGraphCanvas( canvas, graph, options )
};
this.highquality_render = true;
this.use_gradients = false; //set to true to render titlebar with gradients
this.editor_alpha = 1; //used for transition
this.pause_rendering = false;
this.render_shadows = true;
@@ -3040,6 +3065,8 @@ function LGraphCanvas( canvas, graph, options )
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.always_render_background = false;
this.render_canvas_border = true;
this.render_connections_shadows = false; //too much cpu
@@ -3054,15 +3081,10 @@ function LGraphCanvas( canvas, graph, options )
this.onSearchBoxSelection = null;
this.connections_width = 3;
this.round_radius = 8;
this.gui_data = {
node: null,
over_node: null,
local_position: [0,0],
click_position: [0,0],
last_frame_click: false
};
this.current_node = null;
this.node_widget = null; //used for widgets
//link canvas and graph
if(graph)
@@ -3080,7 +3102,7 @@ function LGraphCanvas( canvas, graph, options )
global.LGraphCanvas = LiteGraph.LGraphCanvas = LGraphCanvas;
LGraphCanvas.link_type_colors = {"-1":"#F85",'number':"#AAC","node":"#DCA"};
LGraphCanvas.gradients = {}; //cache of gradients
/**
* clears all the data inside
@@ -3112,6 +3134,7 @@ LGraphCanvas.prototype.clear = function()
this.dirty_area = null;
this.node_in_panel = null;
this.node_widget = null;
this.last_mouse = [0,0];
this.last_mouseclick = 0;
@@ -3537,13 +3560,6 @@ LGraphCanvas.prototype.processMouseDown = function(e)
if(e.which == 1) //left button mouse
{
this.gui_data.clicked_node = node;
if(node)
{
this.gui_data.click_position[0] = e.canvasX - node.pos[0];
this.gui_data.click_position[1] = e.canvasY - node.pos[1];
}
if( e.ctrlKey )
{
this.dragging_rectangle = new Float32Array(4);
@@ -3602,7 +3618,7 @@ LGraphCanvas.prototype.processMouseDown = function(e)
}
//Search for corner
if( !skip_action && isInsideRectangle(e.canvasX, e.canvasY, node.pos[0] + node.size[0] - 5, node.pos[1] + node.size[1] - 5 ,5,5 ))
if( !skip_action && node.flags.resizable !== false && isInsideRectangle(e.canvasX, e.canvasY, node.pos[0] + node.size[0] - 5, node.pos[1] + node.size[1] - 5 ,5,5 ))
{
this.resizing_node = node;
this.canvas.style.cursor = "se-resize";
@@ -3623,11 +3639,12 @@ LGraphCanvas.prototype.processMouseDown = function(e)
var block_drag_node = false;
//widgets
this.gui_data.node = node;
this.gui_data.last_frame_click = true;
if( node.gui_rects )
block_drag_node = this.testGUIRect( node, this.canvas_mouse );
var widget = this.processNodeWidgets( node, this.canvas_mouse, e );
if(widget)
{
block_drag_node = true;
this.node_widget = [node, widget];
}
//double clicking
if ((now - this.last_mouseclick) < 300 && this.selected_nodes[ node.id ])
@@ -3640,7 +3657,6 @@ LGraphCanvas.prototype.processMouseDown = function(e)
}
//if do not capture mouse
if( node.onMouseDown && node.onMouseDown( e, [e.canvasX - node.pos[0], e.canvasY - node.pos[1]] ) )
block_drag_node = true;
else if(this.live_mode)
@@ -3723,6 +3739,11 @@ LGraphCanvas.prototype.processMouseMove = function(e)
this.canvas_mouse[0] = e.canvasX;
this.canvas_mouse[1] = e.canvasY;
if( this.node_widget )
{
this.processNodeWidgets( this.node_widget[0], this.canvas_mouse, e, this.node_widget[1] );
this.dirty_canvas = true;
}
if( this.dragging_rectangle )
{
this.dragging_rectangle[2] = e.canvasX - this.dragging_rectangle[0];
@@ -3844,11 +3865,15 @@ LGraphCanvas.prototype.processMouseMove = function(e)
if(this.resizing_node && !this.live_mode)
{
this.resizing_node.size[0] += delta[0] / this.scale;
this.resizing_node.size[1] += delta[1] / this.scale;
//convert mouse to node space
this.resizing_node.size[0] = e.canvasX - this.resizing_node.pos[0];
this.resizing_node.size[1] = e.canvasY - this.resizing_node.pos[1];
//constraint size
var max_slots = Math.max( this.resizing_node.inputs ? this.resizing_node.inputs.length : 0, this.resizing_node.outputs ? this.resizing_node.outputs.length : 0);
if(this.resizing_node.size[1] < max_slots * LiteGraph.NODE_SLOT_HEIGHT + 4)
this.resizing_node.size[1] = max_slots * LiteGraph.NODE_SLOT_HEIGHT + 4;
var min_height = max_slots * LiteGraph.NODE_SLOT_HEIGHT + ( this.resizing_node.widgets ? this.resizing_node.widgets.length : 0 ) * (LiteGraph.NODE_WIDGET_HEIGHT + 4 ) + 4;
if(this.resizing_node.size[1] < min_height )
this.resizing_node.size[1] = min_height;
if(this.resizing_node.size[0] < LiteGraph.NODE_MIN_WIDTH)
this.resizing_node.size[0] = LiteGraph.NODE_MIN_WIDTH;
@@ -3890,7 +3915,7 @@ LGraphCanvas.prototype.processMouseUp = function(e)
if (e.which == 1) //left button
{
this.gui_data.clicked_node = null;
this.node_widget = null;
if( this.dragging_rectangle )
{
@@ -4544,11 +4569,6 @@ LGraphCanvas.prototype.computeVisibleNodes = function( nodes, out )
if(!overlapBounding( this.visible_area, n.getBounding( temp ) ))
continue; //out of the visible area
//test mouse too
if( this.canvas_mouse[0] > n.pos[0] && this.canvas_mouse[0] <= (n.pos[0] + n.size[0]) &&
this.canvas_mouse[1] > n.pos[1] && this.canvas_mouse[1] <= (n.pos[1] + n.size[1]) )
this.gui_data.over_node = n;
visible_nodes.push(n);
}
return visible_nodes;
@@ -4708,10 +4728,6 @@ LGraphCanvas.prototype.drawFrontCanvas = function()
if(ctx.finish2D) //this is a function I use in webgl renderer
ctx.finish2D();
this.gui_data.node = null;
this.gui_data.over_node = null;
this.gui_data.last_frame_click = false;
}
LGraphCanvas.prototype.renderInfo = function( ctx, x, y )
@@ -4866,8 +4882,8 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var glow = false;
this.current_node = node;
var color = node.color || LiteGraph.NODE_DEFAULT_COLOR;
//if (this.selected) color = "#88F";
var color = node.color || node.constructor.color || LiteGraph.NODE_DEFAULT_COLOR;
var bgcolor = node.bgcolor || node.constructor.bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR;
var render_title = true;
if(node.flags.skip_title_render || node.graph.isLive())
@@ -4876,7 +4892,8 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
render_title = true;
//shadow and glow
if (node.mouseOver) glow = true;
if (node.mouseOver)
glow = true;
if(node.selected)
{
@@ -4910,15 +4927,9 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
return;
}
//draw in collapsed form
/*
if(node.flags.collapsed)
{
if(!node.onDrawCollapsed || node.onDrawCollapsed(ctx) == false)
this.drawNodeCollapsed(node, ctx, color, node.bgcolor);
//custom draw collapsed method
if(node.flags.collapsed && node.onDrawCollaped && node.onDrawCollapsed(ctx, this) == true)
return;
}
*/
var editor_alpha = this.editor_alpha;
ctx.globalAlpha = editor_alpha;
@@ -4927,15 +4938,16 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var shape = node._shape || LiteGraph.BOX_SHAPE;
var size = temp_vec2;
temp_vec2.set( node.size );
if(node.flags.collapsed)
if( node.flags.collapsed )
{
ctx.font = this.inner_text_font;
node._collapsed_width = Math.min( node.size[0], ctx.measureText(node.title).width + 40 );//LiteGraph.NODE_COLLAPSED_WIDTH;
var title = node.getTitle ? node.getTitle() : node.title;
node._collapsed_width = Math.min( node.size[0], ctx.measureText(title).width + 40 );//LiteGraph.NODE_COLLAPSED_WIDTH;
size[0] = node._collapsed_width;
size[1] = 0;
}
if(node.flags.clip_area) //Start clipping
if( node.flags.clip_area ) //Start clipping
{
ctx.save();
ctx.beginPath();
@@ -4949,7 +4961,7 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
}
//draw shape
this.drawNodeShape( node, ctx, size, color, node.bgcolor, !render_title, node.selected );
this.drawNodeShape( node, ctx, size, color, bgcolor, !render_title, node.selected );
ctx.shadowColor = "transparent";
//connection slots
@@ -4959,6 +4971,9 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var render_text = this.scale > 0.6;
var out_slot = this.connecting_output;
ctx.lineWidth = 1;
var max_y = 0;
//render inputs and outputs
if(!node.flags.collapsed)
@@ -4970,15 +4985,17 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var slot = node.inputs[i];
ctx.globalAlpha = editor_alpha;
//change opacity of incompatible slots
//change opacity of incompatible slots when dragging a connection
if ( this.connecting_node && LiteGraph.isValidConnection( slot.type && out_slot.type ) )
ctx.globalAlpha = 0.4 * editor_alpha;
ctx.fillStyle = slot.link != null ? this.default_connection_color.input_on : this.default_connection_color.input_off;
var pos = node.getConnectionPos(true,i);
var pos = node.getConnectionPos( true, i );
pos[0] -= node.pos[0];
pos[1] -= node.pos[1];
if( max_y < pos[1] + LiteGraph.NODE_SLOT_HEIGHT*0.5 )
max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT*0.5;
ctx.beginPath();
@@ -5005,8 +5022,6 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
if(this.connecting_node)
ctx.globalAlpha = 0.4 * editor_alpha;
ctx.lineWidth = 1;
ctx.textAlign = "right";
ctx.strokeStyle = "black";
if(node.outputs)
@@ -5017,6 +5032,8 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
var pos = node.getConnectionPos(false,i);
pos[0] -= node.pos[0];
pos[1] -= node.pos[1];
if( max_y < pos[1] + LiteGraph.NODE_SLOT_HEIGHT*0.5)
max_y = pos[1] + LiteGraph.NODE_SLOT_HEIGHT*0.5;
ctx.fillStyle = slot.links && slot.links.length ? this.default_connection_color.output_on : this.default_connection_color.output_off;
ctx.beginPath();
@@ -5050,14 +5067,15 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
ctx.textAlign = "left";
ctx.globalAlpha = 1;
if(node.widgets)
this.drawNodeWidgets( node, max_y, ctx, (this.node_widget && this.node_widget[0] == node) ? this.node_widget[1] : null );
//draw foreground
if(node.onDrawForeground)
{
//immediate gui stuff
if( node.gui_rects )
node.gui_rects.length = 0;
this.gui_data.local_position[0] = this.canvas_mouse[0] - node.pos[0];
this.gui_data.local_position[1] = this.canvas_mouse[1] - node.pos[1];
node.onDrawForeground( ctx, this );
}
}
@@ -5112,39 +5130,34 @@ LGraphCanvas.prototype.drawNode = function(node, ctx )
LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolor, no_title, selected )
{
//bg rect
ctx.strokeStyle = fgcolor || LiteGraph.NODE_DEFAULT_COLOR;
ctx.fillStyle = bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR;
/* gradient test
var grad = ctx.createLinearGradient(0,0,0,node.size[1]);
grad.addColorStop(0, "#AAA");
grad.addColorStop(0.5, fgcolor || LiteGraph.NODE_DEFAULT_COLOR);
grad.addColorStop(1, bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR);
ctx.fillStyle = grad;
//*/
ctx.strokeStyle = fgcolor;
ctx.fillStyle = bgcolor;
var title_height = LiteGraph.NODE_TITLE_HEIGHT;
//render node area depending on shape
var shape = node._shape || LiteGraph.BOX_SHAPE;
if(shape == LiteGraph.BOX_SHAPE)
var shape = node._shape || node.constructor.shape || LiteGraph.BOX_SHAPE;
if(!node.flags.collapsed)
{
ctx.beginPath();
ctx.rect(0,no_title ? 0 : -title_height, size[0]+1, no_title ? size[1] : size[1] + title_height);
ctx.fill();
ctx.shadowColor = "transparent";
}
else if (shape == LiteGraph.ROUND_SHAPE)
{
ctx.beginPath();
ctx.roundRect(0,no_title ? 0 : -title_height,size[0], no_title ? size[1] : size[1] + title_height, title_height*0.5);
ctx.fill();
}
else if (shape == LiteGraph.CIRCLE_SHAPE)
{
ctx.beginPath();
ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5, 0, Math.PI*2);
ctx.fill();
if(shape == LiteGraph.BOX_SHAPE || this.scale < 0.5)
{
ctx.beginPath();
ctx.rect(0,no_title ? 0 : -title_height, size[0]+1, no_title ? size[1] : size[1] + title_height);
ctx.fill();
}
else if (shape == LiteGraph.ROUND_SHAPE || shape == LiteGraph.CARD_SHAPE)
{
ctx.beginPath();
ctx.roundRect(0,no_title ? 0 : -title_height,size[0], no_title ? size[1] : size[1] + title_height, this.round_radius, shape == LiteGraph.CARD_SHAPE ? 0 : this.round_radius);
ctx.fill();
}
else if (shape == LiteGraph.CIRCLE_SHAPE)
{
ctx.beginPath();
ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5, 0, Math.PI*2);
ctx.fill();
}
}
ctx.shadowColor = "transparent";
@@ -5160,31 +5173,45 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
//immediate gui stuff
if( node.gui_rects )
node.gui_rects.length = 0;
this.gui_data.local_position[0] = this.canvas_mouse[0] - node.pos[0];
this.gui_data.local_position[1] = this.canvas_mouse[1] - node.pos[1];
node.onDrawBackground( ctx, this );
}
//title bg (remember, it is rendered ABOVE the node
if(!no_title)
{
if(!node.flags.collapsed)
//title bar
if(1) //!node.flags.collapsed)
{
ctx.fillStyle = fgcolor || LiteGraph.NODE_DEFAULT_COLOR;
//* gradient test
if(this.use_gradients)
{
var grad = LGraphCanvas.gradients[ fgcolor ];
if(!grad)
{
grad = LGraphCanvas.gradients[ fgcolor ] = ctx.createLinearGradient(0,0,400,0);
grad.addColorStop(0, fgcolor);
grad.addColorStop(1, "#000");
}
ctx.fillStyle = grad;
}
else
ctx.fillStyle = fgcolor;
var old_alpha = ctx.globalAlpha;
//ctx.globalAlpha = 0.5 * old_alpha;
ctx.beginPath();
if(shape == LiteGraph.BOX_SHAPE)
if(shape == LiteGraph.BOX_SHAPE || this.scale < 0.5)
{
ctx.rect(0, -title_height, size[0]+1, title_height);
ctx.fill()
//ctx.stroke();
}
else if (shape == LiteGraph.ROUND_SHAPE)
else if (shape == LiteGraph.ROUND_SHAPE || shape == LiteGraph.CARD_SHAPE)
{
ctx.roundRect(0,-title_height,size[0], title_height,10, node.flags.collapsed ? 10 : 0);
ctx.roundRect(0,-title_height,size[0], title_height, this.round_radius, node.flags.collapsed ? this.round_radius : 0);
ctx.fill();
}
/*
else if (shape == LiteGraph.CIRCLE_SHAPE)
{
@@ -5198,7 +5225,7 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
//title box
ctx.fillStyle = node.boxcolor || LiteGraph.NODE_DEFAULT_BOXCOLOR;
ctx.beginPath();
if (shape == LiteGraph.ROUND_SHAPE || shape == LiteGraph.CIRCLE_SHAPE)
if (shape == LiteGraph.ROUND_SHAPE || shape == LiteGraph.CIRCLE_SHAPE || shape == LiteGraph.CARD_SHAPE)
ctx.arc(title_height *0.5, title_height * -0.5, (title_height - 8) *0.5,0,Math.PI*2);
else
ctx.rect(4,-title_height + 4,title_height - 8,title_height - 8);
@@ -5206,23 +5233,25 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
ctx.globalAlpha = old_alpha;
//title text
ctx.font = this.title_text_font;
var title = node.getTitle();
if(title && this.scale > 0.5)
if( this.scale > 0.5 )
{
if( node.flags.collapsed )
ctx.font = this.title_text_font;
var title = node.getTitle();
if(title)
{
ctx.textAlign = "center";
ctx.fillStyle = this.node_title_color;
var measure = ctx.measureText(title);
ctx.fillText( title, title_height + measure.width * 0.5, -title_height * 0.2 );
ctx.textAlign = "left";
}
else
{
ctx.textAlign = "left";
ctx.fillStyle = this.node_title_color;
ctx.fillText( title, title_height, -title_height * 0.2 );
ctx.fillStyle = node.constructor.title_text_color || this.node_title_color;
if( node.flags.collapsed )
{
ctx.textAlign = "center";
var measure = ctx.measureText(title);
ctx.fillText( title, title_height + measure.width * 0.5, -title_height * 0.2 );
ctx.textAlign = "left";
}
else
{
ctx.textAlign = "left";
ctx.fillText( title, title_height, -title_height * 0.2 );
}
}
}
}
@@ -5233,74 +5262,19 @@ LGraphCanvas.prototype.drawNodeShape = function(node, ctx, size, fgcolor, bgcolo
ctx.lineWidth = 1;
ctx.beginPath();
if(shape == LiteGraph.BOX_SHAPE)
ctx.rect(-4,-4 + (no_title ? 0 : -title_height), 8 + size[0]+1, 8 + (no_title ? size[1] : size[1] + title_height));
ctx.rect(-6,-6 + (no_title ? 0 : -title_height), 12 + size[0]+1, 12 + (no_title ? size[1] : size[1] + title_height));
else if (shape == LiteGraph.ROUND_SHAPE)
ctx.roundRect(-4, -4 + (no_title ? 0 : -title_height), 8 + size[0], 8 + (no_title ? size[1] : size[1] + title_height), title_height*0.7);
ctx.roundRect(-6, -6 + (no_title ? 0 : -title_height), 12 + size[0], 12 + (no_title ? size[1] : size[1] + title_height), this.round_radius * 2);
else if (shape == LiteGraph.CARD_SHAPE)
ctx.roundRect(-6, -6 + (no_title ? 0 : -title_height), 12 + size[0], 12 + (no_title ? size[1] : size[1] + title_height), this.round_radius * 2, 0);
else if (shape == LiteGraph.CIRCLE_SHAPE)
ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5 + 4, 0, Math.PI*2);
ctx.arc(size[0] * 0.5, size[1] * 0.5, size[0] * 0.5 + 6, 0, Math.PI*2);
ctx.strokeStyle = "#DDD";
ctx.stroke();
ctx.strokeStyle = fgcolor;
}
}
/* Renders the node when collapsed */
// NOT IN USE RIGHT NOW, DEPRECATED!!!!!!!!!!!!!!!!!!!!!
/*
LGraphCanvas.prototype.drawNodeCollapsed = function(node, ctx, fgcolor, bgcolor)
{
//draw default collapsed shape
ctx.strokeStyle = fgcolor || LiteGraph.NODE_DEFAULT_COLOR;
ctx.fillStyle = bgcolor || LiteGraph.NODE_DEFAULT_BGCOLOR;
var collapsed_radius = LiteGraph.NODE_COLLAPSED_RADIUS;
var shape = node._shape || LiteGraph.BOX_SHAPE;
if(shape == LiteGraph.CIRCLE_SHAPE) //circle shape
{
ctx.beginPath();
ctx.arc(node.size[0] * 0.5, node.size[1] * 0.5, collapsed_radius,0,Math.PI * 2);
ctx.fill();
ctx.shadowColor = "rgba(0,0,0,0)";
ctx.stroke();
ctx.fillStyle = node.boxcolor || LiteGraph.NODE_DEFAULT_BOXCOLOR;
ctx.beginPath();
ctx.arc(node.size[0] * 0.5, node.size[1] * 0.5, collapsed_radius * 0.5,0,Math.PI * 2);
ctx.fill();
}
else if(shape == LiteGraph.ROUND_SHAPE) //rounded box
{
ctx.beginPath();
ctx.roundRect(node.size[0] * 0.5 - collapsed_radius, node.size[1] * 0.5 - collapsed_radius, 2*collapsed_radius,2*collapsed_radius,collapsed_radius*0.5);
ctx.fill();
ctx.shadowColor = "rgba(0,0,0,0)";
ctx.stroke();
ctx.fillStyle = node.boxcolor || LiteGraph.NODE_DEFAULT_BOXCOLOR;
ctx.beginPath();
ctx.roundRect(node.size[0] * 0.5 - collapsed_radius*0.5, node.size[1] * 0.5 - collapsed_radius*0.5, collapsed_radius,collapsed_radius,2);
ctx.fill();
}
else //flat box
{
ctx.beginPath();
//ctx.rect(node.size[0] * 0.5 - collapsed_radius, node.size[1] * 0.5 - collapsed_radius, 2*collapsed_radius, 2*collapsed_radius);
ctx.rect(0, 0, node.size[0], collapsed_radius * 2 );
ctx.fill();
ctx.shadowColor = "rgba(0,0,0,0)";
ctx.stroke();
ctx.fillStyle = node.boxcolor || LiteGraph.NODE_DEFAULT_BOXCOLOR;
ctx.beginPath();
//ctx.rect(node.size[0] * 0.5 - collapsed_radius*0.5, node.size[1] * 0.5 - collapsed_radius*0.5, collapsed_radius,collapsed_radius);
ctx.rect(collapsed_radius*0.5, collapsed_radius*0.5, collapsed_radius, collapsed_radius);
ctx.fill();
}
}
*/
//OPTIMIZE THIS: precatch connections position instead of recomputing them every time
LGraphCanvas.prototype.drawConnections = function(ctx)
{
@@ -5469,32 +5443,98 @@ LGraphCanvas.prototype.computeConnectionPoint = function(a,b,t)
return [x,y];
}
LGraphCanvas.prototype.addGUIRect = function( node, rect )
LGraphCanvas.prototype.drawNodeWidgets = function( node, posY, ctx, active_widget )
{
if(!node.gui_rects)
node.gui_rects = [];
if(node.gui_rects.length > 10) //safety first
return;
node.gui_rects.push( rect );
if(!node.widgets || !node.widgets.length)
return 0;
var width = node.size[0];
var widgets = node.widgets;
posY += 2;
for(var i = 0; i < widgets.length; ++i)
{
var w = widgets[0];
var y = posY;
if(w.y)
y = w.y;
w.last_y = y;
ctx.strokeStyle = "#AAA";
ctx.fillStyle = "#222";
ctx.textAlign = "left";
switch( w.type )
{
case "button":
if(w.clicked)
{
ctx.fillStyle = "#AAA";
w.clicked = false;
this.dirty_canvas = true;
}
ctx.fillRect(6.5,y,width-12,20);
ctx.strokeRect(6.5,y,width-12,20);
ctx.textAlign = "center";
ctx.fillStyle = "#AAA";
ctx.fillText( w.name, width*0.5, y + 20*0.7 );
break;
case "slider":
ctx.fillRect(6.5,y,width-12,20);
var range = w.options.max - w.options.min;
var nvalue = (w.value - w.options.min) / range;
ctx.fillStyle = active_widget == w ? "#89A" : "#678";
ctx.fillRect(6.5,y,nvalue*(width-12),20);
ctx.strokeRect(6.5,y,width-12,20);
ctx.textAlign = "center";
ctx.fillStyle = "#CCC";
ctx.fillText( w.name + " " + Number(w.value).toFixed(3), width*0.5, y + 20*0.7 );
break;
}
posY += 20;
}
ctx.textAlign = "left";
}
LGraphCanvas.prototype.testGUIRect = function( node, pos )
LGraphCanvas.prototype.processNodeWidgets = function( node, pos, event, active_widget )
{
if(!node.gui_rects || !node.gui_rects.length)
return false;
if(!node.widgets || !node.widgets.length)
return null;
var x = pos[0] - node.pos[0];
var y = pos[1] - node.pos[1];
var width = node.size[0];
var that = this;
for(var i = 0; i < node.gui_rects.length; ++i)
for(var i = 0; i < node.widgets.length; ++i)
{
var rect = node.gui_rects[i];
if( x > rect[0] && x < (rect[0] + rect[2]) && y > rect[1] && y < (rect[1] + rect[3]) )
return true
var w = node.widgets[i];
if( w == active_widget || (x > 6 && x < (width - 12) && y > w.last_y && y < (w.last_y + LiteGraph.NODE_WIDGET_HEIGHT)) )
{
//inside widget
switch( w.type )
{
case "button":
if(w.callback)
setTimeout( function(){ w.callback( w, that, node, pos ); }, 20 );
w.clicked = true;
this.dirty_canvas = true;
break;
case "slider":
var range = w.options.max - w.options.min;
var nvalue = Math.clamp( (x - 6) / (width - 12), 0, 1);
w.value = w.options.min + (w.options.max - w.options.min) * nvalue;
if(w.callback)
setTimeout( function(){ w.callback( w.value, that, node, pos ); }, 20 );
this.dirty_canvas = true;
break;
}
return w;
}
}
return false;
return null;
}
/*
LGraphCanvas.prototype.guiButton = function( ctx, rect, text, callback )
{
if(!rect)
@@ -5590,6 +5630,7 @@ LGraphCanvas.prototype.guiSlider = function( ctx, rect, value, left_value, right
return value;
}
*/
/*
LGraphCanvas.prototype.resizeCanvas = function(width,height)
@@ -5716,7 +5757,7 @@ LGraphCanvas.onMenuAdd = function( node, options, e, prev_menu )
function inner_clicked( v, option, e )
{
var category = v.value;
var node_types = LiteGraph.getNodeTypesInCategory(category);
var node_types = LiteGraph.getNodeTypesInCategory( category, canvas.filter );
var values = [];
for(var i in node_types)
values.push( { content: node_types[i].title, value: node_types[i].type });
@@ -6355,10 +6396,12 @@ LGraphCanvas.onMenuNodeColors = function( value, options, e, menu, node )
throw("no node for color");
var values = [];
values.push({ value:null, content:"<span style='display: block; padding-left: 4px;'>No color</span>" });
for(var i in LGraphCanvas.node_colors)
{
var color = LGraphCanvas.node_colors[i];
var value = {value:i, content:"<span style='display: block; color: #999; padding-left: 4px; border-left: 8px solid "+color.color+"; background-color:"+color.bgcolor+"'>"+i+"</span>"};
var value = { value:i, content:"<span style='display: block; color: #999; padding-left: 4px; border-left: 8px solid "+color.color+"; background-color:"+color.bgcolor+"'>"+i+"</span>" };
values.push(value);
}
new LiteGraph.ContextMenu( values, { event: e, callback: inner_clicked, parentMenu: menu, node: node });
@@ -6368,13 +6411,18 @@ LGraphCanvas.onMenuNodeColors = function( value, options, e, menu, node )
if(!node)
return;
var color = LGraphCanvas.node_colors[ v.value ];
var color = v.value ? LGraphCanvas.node_colors[ v.value ] : null;
if(color)
{
node.color = color.color;
node.bgcolor = color.bgcolor;
node.setDirtyCanvas(true);
}
else
{
delete node.color;
delete node.bgcolor;
}
node.setDirtyCanvas(true);
}
return false;
@@ -6422,8 +6470,10 @@ LGraphCanvas.onMenuNodeClone = function( value, options, e, menu, node )
LGraphCanvas.node_colors = {
"red": { color:"#322", bgcolor:"#533" },
"brown": { color:"#332922", bgcolor:"#593930" },
"green": { color:"#232", bgcolor:"#353" },
"blue": { color:"#223", bgcolor:"#335" },
"pale_blue": { color:"#2a363b", bgcolor:"#3f5159" },
"cyan": { color:"#233", bgcolor:"#355" },
"purple": { color:"#323", bgcolor:"#535" },
"yellow": { color:"#432", bgcolor:"#653" },

View File

@@ -39,6 +39,8 @@ function Subgraph()
this.subgraph.onGlobalOutputAdded = this.onSubgraphNewGlobalOutput.bind(this);
this.subgraph.onGlobalOutputRenamed = this.onSubgraphRenamedGlobalOutput.bind(this);
this.subgraph.onGlobalOutputTypeChanged = this.onSubgraphTypeChangeGlobalOutput.bind(this);
this.addWidget("button","Open Graph",null,function( widget, graphcanvas ){ graphcanvas.openSubgraph(that.subgraph) });
this.bgcolor = "#353";
}
@@ -109,10 +111,12 @@ Subgraph.prototype.getExtraMenuOptions = function(graphcanvas)
Subgraph.prototype.onDrawForeground = function( ctx, graphcanvas )
{
/*
var node = this;
ctx.globalAlpha = 0.75;
graphcanvas.guiButton( ctx, [0,this.size[1] - 20, this.size[0], 19 ], "Open", function(){ graphcanvas.openSubgraph(node.subgraph); });
ctx.globalAlpha = 1;
*/
}
Subgraph.prototype.onResize = function(size)

View File

@@ -414,26 +414,33 @@ var LiteGraph = global.LiteGraph;
//Show value inside the debug console
function WidgetSliderGUI()
{
this.addOutput("v","number");
this.addOutput("","number");
this.properties = {
value: 0.5,
min: 0,
max: 1,
text: "V"
text: "V",
y: 2
};
var that = this;
this.size = [80,60];
this.slider = this.addWidget("slider","V", this.properties.value, function(v){ that.properties.value = v; }, this.properties );
}
WidgetSliderGUI.title = "Internal Slider";
WidgetSliderGUI.prototype.onDrawBackground = function( ctx, graphcanvas )
WidgetSliderGUI.prototype.onPropertyChanged = function(name,value)
{
var node = this;
ctx.globalAlpha = 0.75;
this.properties.value = graphcanvas.guiSlider( ctx, [2, 2, this.size[0] - 4, this.size[1] - 4], this.properties.value, this.properties.min, this.properties.max, this.properties.text );
ctx.globalAlpha = 1;
if(name == "value")
this.slider.value = value;
}
WidgetSliderGUI.prototype.onExecute = function()
{
this.setOutputData(0,this.properties.value);
}
LiteGraph.registerNodeType("widget/internal_slider", WidgetSliderGUI );
//Widget H SLIDER