3 'remoto!stdlib:js/panes/panes/nodeCanvas/nodeDefines.js',
4 'remoto!stdlib:js/include/objectRegistry.js',
5 'remoto!stdlib:js/widgets/widgetFactory.js',
6 'remoto!stdlib:js/widgets/widgets/groupWidget.js',
7 'remoto!stdlib:js/widgets/widgets/numberWidget.js',
8 'remoto!stdlib:js/panes/panes/nodeCanvas/plug.js',
9 'remoto!stdlib:js/panes/panes/nodeCanvas/cable.js',
10 'remoto!stdlib:js/include/preferences.js',
11 'remoto!stdlib:js/include/utils.js',
12 'remoto!stdlib:js/include/color.js',
13 'remoto!stdlib:js/panes/panes/nodeCanvas/node.css',
19 var svgns =
"http://www.w3.org/2000/svg";
21 var snapDistance = defines.snapDistance;
48 node.icon =
"data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-7 -7 14 14\"><circle vector-effect=\"non-scaling-stroke\" class=\"nodeBackground\" fill=\"%23FF6666\" stroke=\"%232F2\" cx=\"0\" cy=\"0\" r=\"6\"></circle></svg>";
57 function node( _path, _cnv, _attrs, _in, _out, _base, _icon )
74 tip:
"Node position and color",
92 change: (
function(variable,
value,
widget) { THIS.color =
value; } ).bind(
this),
101 change: (
function(variable,
value,
widget) { THIS.name =
value; } ).bind(
this),
105 tip:
"Node progress",
109 change: (
function(variable,
value,
widget) { THIS.progress =
value; } ).bind(
this),
112 this._attributes = {};
115 this._selected =
false;
116 this._moving =
false;
117 this._boundingBox = {
x:0,
y:0,width:0,height:0};
119 this._diffing =
false;
120 this._firstLoad =
true;
121 this._diffTimer =
null;
126 this._background =
null;
127 this._gradient =
null;
130 this._progress =
null;
133 this._hideInputLabels =
false;
134 this._hideOutputLabels =
false;
136 if (!arguments.length)
return;
142 _path = this._canvas._path+
"/"+n_id+
".rnd";
146 this._base = _base ||
"node.rnd";
151 for( var ii in this._inputsSpec ) {
delete this._inputsSpec[ii].value; }
155 for( var dd in this._outputsSpec ) {
delete this._outputsSpec[dd].value; }
157 this._icon = _icon ||
node.icon;
158 this._layer = this._layer ||
"nodes";
160 this._nodeClass = this._nodeClass ||
node;
167 setTimeout( this.
resize.bind(
this), 0 );
170 this._attributes.uuid.value = n_id;
172 this._root.trigger(
"nodecreated", {
node:
this } );
173 this._root.trigger(
"undoevent", {
type:
"Create Node: "+this.
name+
" "+this._path,
undo:this.
detach.bind(
this),
redo:this.
attach.bind(
this), close:
true } );
190 if (this._root)
return;
193 var p = this._canvas._layers[this._layer];
194 var g = this._root = $( document.createElementNS(svgns,
"g") ).appendTo(p).attr( {
class:
"node" } );
199 "vector-effect":
"non-scaling-stroke",
203 var b = this._background = $( document.createElementNS(svgns,
"rect") ).appendTo(g);
209 "vector-effect":
"non-scaling-stroke",
211 "class":
"nodeBackground",
215 var prog = this._progress = $( document.createElementNS(svgns,
"rect") ).appendTo(g);
225 var grad = this._gradient = $( document.createElementNS(svgns,
"rect") ).appendTo(g);
230 fill:
"url(#"+this._canvas._id+
"_nodeGradient)",
231 "vector-effect":
"non-scaling-stroke",
233 "class":
"nodeBackgroundGradient",
236 var l = this._label = $( document.createElementNS(svgns,
"text") ).appendTo(g);
242 "text-anchor":
"middle",
247 var t = this._title = $( document.createElementNS(svgns,
"title") ).appendTo(g);
268 var b = this._background;
272 b.bind(
"mouseover",
function(evt)
275 THIS._root.trigger(
"plugcandidate", {
node:THIS} );
279 b.bind(
"mouseout",
function(evt)
282 THIS._root.trigger(
"plugcandidate", {
plug:
null} );
286 b.bind(
"mouseup",
function(evt)
288 THIS._root.trigger(
"plugaccept" );
292 r.bind(
"plugsplit",
function(evt,data)
299 r.bind(
"plugunsplit",
function(evt,data)
306 r.bind(
"plugconnect plugdisconnect",
function(evt,data)
312 r.bind(
"plugdestroy",
function(evt,data)
315 var a = p._isInput ? THIS._inputs : THIS._outputs;
333 detach:
function(createUndo)
339 for (var i in this._inputs)
340 this._inputs[i].detach();
342 for (var o in this._outputs)
343 this._outputs[o].detach();
345 for (var i=0;i<bridges.length;i++)
348 var c =
new cable( this._canvas, this._canvas.getPlug(b.source,
plug.OUTPUT,
true),
this._canvas.getPlug(b.dest,
plug.INPUT,
true) );
356 this._canvas._root.trigger(
"nodedetached", {
node:
this} );
359 this._canvas._root.trigger(
"undoevent", {
type:
"Node Delete: "+this.
name+
" "+this._path,
undo:this.
attach.bind(
this),
redo:this.
detach.bind(
this) } );
374 var l = this._canvas._layers[this._layer];
375 this._root.appendTo( l );
378 this._canvas._root.trigger(
"nodeattached", {
node:
this} );
395 for (var i in this._inputs)
396 this._inputs[i].destroy();
398 for (var o in this._outputs)
399 this._outputs[o].destroy();
401 for (var i=0;i<bridges.length;i++)
404 var c =
new cable( this._canvas, b.source, b.dest );
409 this._outputs =
null;
414 for (var a in this._attributes)
415 this._attributes[a].destroy();
416 this._attributes =
null;
418 this._canvas._root.trigger(
"nodedestroyed", {
node:
this} );
440 var ss = this._canvas._objectLoader.fetchDefinition(
445 return spec.attributes;
454 paste:this._nodeClass.bind(
null,
null,this._canvas,ss,this._inputsSpec,this._outputsSpec,this._base,this._icon),
457 var a = [ this._inputs, this._outputs ];
458 a.forEach(
function(b)
462 c.push( { step:2, action:
"createcable", source:b[p]._cable._source.path, dest:b[p]._cable._dest.path } );
484 var c =
utils.
keyCountFiltered(_in,
function(e) {
return _in[e].type ? (_in[e].type.indexOf(
"<")==-1) :
false; } );
487 {
if (i.indexOf(
".") != -1)
488 throw "Can't create plugs with '.' in name. '"+i+
"' provided.";
490 p = this._inputs[i] =
new plug(
this, i,
plug.INPUT, _in[i].
type );
493 this._hideInputLabels =
true;
499 var ia = _in[i].value;
502 for (var j=0; j<ia.length; j++)
507 var sp = this._canvas.getPlug( iap,
plug.OUTPUT,
true );
511 this._canvas.globalDiffing =
true;
512 var c =
new cable( this._canvas, sp, p );
514 this._canvas.globalDiffing =
false;
543 {
if (o.indexOf(
".") != -1)
544 throw "Can't create plugs with '.' in name. '"+o+
"' provided.";
546 p = this._outputs[o] =
new plug(
this, o,
plug.OUTPUT, _out[o].
type );
549 this._hideOutputLabels =
true;
555 var oa = _out[o].value;
558 for (var i=0; i<oa.length; i++)
563 var dp = this._canvas.getPlug( oap,
plug.INPUT,
true );
567 this._canvas.globalDiffing =
true;
568 var c =
new cable( this._canvas, p, dp );
570 this._canvas.globalDiffing =
false;
604 for (var __i=0;__i < sorted.length; __i++)
606 v = sorted[__i].__key;
609 if (!d || (typeof d !==
"object"))
continue;
612 d.change = d.change || this.
changeField.bind(
this);
618 { this._attributes[v] = w;
660 if (variable in
this)
661 this[variable] =
value;
666 if (this._diffing || this._canvas.globalDiffing)
672 var c = { attributes:e };
679 if (!this._diffTimer)
681 this._diffTimer = setTimeout(
function()
684 if (!THIS._firstLoad)
685 THIS._root.trigger(
"nodechange", [
"diff", THIS._diff ] );
686 THIS._firstLoad =
false;
688 THIS._canvas.globalDiffing =
true;
689 THIS._canvas._diffing =
true;
691 THIS._canvas._diffing =
false;
692 THIS._canvas.globalDiffing =
false;
694 THIS._diffTimer =
null;
764 console.log(
"node diff was null. returning.");
768 this._diffing =
true;
770 if (
"attributes" in diff)
772 var d = diff[
"attributes"];
778 if (!(v instanceof Object))
783 if (a in this._attributes)
785 this._attributes[a].immediateValue = v.value;
804 if (
"inputs" in diff)
806 var d = diff[
"inputs"];
811 if (!(v instanceof Object))
816 if (v.value ===
null)
820 for (var i=0;i < dp.length; i++)
822 dp[i]._cable.destroy();
832 var dlist = cc.filter(
function(p) {
return ( ia.indexOf(p.connectedPlug().pathString) == -1 ); } );
833 dlist.forEach(
function(p) { p._cable.destroy(); } );
835 for (var i = 0; i< ia.length; i++)
840 var sp = this._canvas.getPlug( iap,
plug.OUTPUT,
true );
848 var c =
new cable( this._canvas, sp, dp );
864 if (
"outputs" in diff)
866 var d = diff[
"outputs"];
871 if (!(v instanceof Object))
876 if (v.value ===
null)
880 for (var i=0;i<sp.length; i++)
882 sp[i]._cable.destroy();
892 var dlist = cc.filter(
function(p) {
return ( oa.indexOf(p.connectedPlug().pathString) == -1 ); } );
893 dlist.forEach(
function(p) { p._cable.destroy(); } );
895 for (var i = 0; i< oa.length; i++)
901 var dp = this._canvas.getPlug( oap,
plug.INPUT,
true );
908 var c =
new cable( this._canvas, sp, dp );
924 if (
"selection" in diff)
926 console.log(
"node selection change!");
929 this._diffing =
false;
976 this._canvas._objectLoader.fetchDefinition( this._nodeClass.base, {}, this.
baseValues.bind(
this,callback) );
1007 for (var a in this._attributes)
1009 v = this._attributes[a].nonDefaultValue;
1010 if (v !== undefined)
1011 diff[
"attributes"][a] = v;
1015 for (var a in this._inputs)
1017 p = this._inputs[a];
1020 diff[
"inputs"][p._name] = {
value:v };
1024 for (var a in this._outputs)
1026 p = this._outputs[a];
1029 diff[
"outputs"][p._name] = {
value:v };
1053 var a = input ? this._inputs : this._outputs;
1057 return a[i]._cable.otherEnd( a[i] )._node;
1074 getPlug:
function(n,input,firstAvailable)
1077 var a = input ? this._inputs : this._outputs;
1090 {
if (t.connected && t.connectedPlug())
1100 return firstAvailable ? null : [];
1123 var a = p._isInput ? this._inputs : this._outputs;
1129 var _p =
new plug(
this, k, p._isInput, p._originalType );
1131 if ((p._isInput &&
this._hideInputLabels) || (!p._isInput &&
this._hideOutputLabels))
1140 if (p._isInput) this._inputs = a;
1141 else this._outputs = a;
1161 var a = p._isInput ? this._inputs : this._outputs;
1163 var ks = Object.keys(a);
1165 for (var i = ks.length-1; i>=0; i--)
1166 if (a[ks[i]]._name == k && a[ks[i]].
idle)
1173 {
if (ks.length == 2)
1188 { console.log(
this);
1189 throw "Could not unspslit the plug... nothing available called '"+k+
"'";
1208 while( k+
"."+i in a && i<100 )
1211 if (i>=100)
throw "Can't split plug... too many plugs named '"+k+
"'";
1230 if (c && (p = c.otherEnd(pp)))
1232 if (p._node ==
this)
1235 var t = p.resolvedType(
true);
1236 var a = p._isInput ? this._outputs : this._inputs;
1262 for (var i in this._inputs)
1263 this._inputs[i].show();
1265 for (var o in this._outputs)
1266 this._outputs[o].show();
1280 for (var i in this._inputs)
1282 var ip = this._inputs[i];
1292 for (var o in this._outputs)
1294 var op = this._outputs[o];
1317 for (var i in this._inputs)
1321 for (var o in this._outputs)
1326 if (s.type == d.type)
1327 return [ { source:s.path, dest:d.path } ];
1391 if (arguments.length)
1395 x = Math.round(
x*10)/10;
1396 y = Math.round(
y*10)/10;
1402 this._attributes.node.immediateValue = v;
1407 requestAnimationFrame(
function()
1410 utils.
setAttr( THIS._root[0], {
"transform":
"translate("+THIS.x+
","+THIS.y+
")" } );
1413 for (var i in this._inputs)
1414 this._inputs[i].refreshCables();
1416 for (var o in this._outputs)
1417 this._outputs[o].refreshCables();
1420 return {
x:this.
x,
y:this.
y };
1437 var boundsPointingTo =
function(px,
py,
x,
y, w, h, a)
1442 var theta = Math.atan2(-
y,-
x);
1447 var phi = Math.atan2(
py,px);
1448 if ( Math.abs(phi) <= theta ) quad = 0;
1449 else if ( Math.abs(phi) >= Math.PI - theta ) quad = 2;
1450 else if ( phi >= theta ) quad = 1;
1460 {
case 0: rx = w/2; ry = Math.tan( phi ) * w/2;
break;
1461 case 1: ry = h/2; rx = 1/Math.tan( phi ) * h/2;
break;
1462 case 2: rx = -w/2; ry = Math.tan( -phi ) * w/2;
break;
1463 case 3: ry = -h/2; rx = -1/Math.tan( phi ) * h/2;
break;
1473 dist = (dist !== undefined) ? dist : 3;
1476 var b = this._boundingBox;
1487 pt1.x = pt.x - this.
x;
1488 pt1.y = pt.y - this.
y;
1489 var pt2 = boundsPointingTo( pt1.x, pt1.y, b.x, b.y, b.width, b.height,a );
1490 pt1.x = pt2.x + this.
x;
1491 pt1.y = pt2.y + this.
y;
1495 labelPoint.x = Math.cos(a.theta) * ldist;
1496 labelPoint.y = Math.sin(a.theta) * ldist;
1516 var bb = this._label[0].getBBox();
1517 var b = this._background;
1518 var g = this._gradient;
1519 var p = this._progress;
1521 var
x = -bb.width/2-paddingw*2;
1522 var
y = -bb.height/2-paddingh;
1523 var w = bb.width+paddingw*4;
1524 var h = bb.height+paddingh*2;
1534 this._boundingBox = a;
1544 pp.display =
"none";
1547 var sf =
function(k,o) {
return (!o[k].
connected && !o[k].
mask); };
1548 var mf =
function(k,o) {
return (o[k].
mask); };
1552 s = Math.min( s, 10 );
1554 var xc = -((ic-1)*s)/2;
1555 for (var i in this._inputs)
1556 {
if (this._inputs[i].
connected || this._inputs[i].
mask)
continue;
1557 this._inputs[i].position(xc,
y);
1563 console.warn(
"Don't know how to position more than one mask input");
1564 for (var i in this._inputs)
1565 {
if (this._inputs[i].
connected || !this._inputs[i].
mask)
continue;
1566 this._inputs[i].position(w/2,0);
1571 s = Math.min( s, 10 );
1574 var xc = -((oc-1)*s)/2;
1575 for (var o in this._outputs)
1576 {
if (this._outputs[o].
connected)
continue;
1577 this._outputs[o].position(xc,
y+h);
1596 this._startPos.x = this.
x;
1597 this._startPos.y = this.
y;
1601 this._background.attr( {
"class":
"nodeBackgroundNoPointer" } );
1603 this._moving =
true;
1625 if (
"x" in this._startPos &&
"y" in this._startPos)
1626 if (this._startPos.x !==
this.x ||
this._startPos.y !==
this.y)
1627 this._root.trigger(
"undoevent", {
type:
"Move Node: "+this.
name,
undo:this.
position.bind(
this,this._startPos.x,
this._startPos.y),
redo:this.
position.bind(
this,this.x,this.y) } );
1629 this._background.attr( {
"class":
"nodeBackground" } );
1631 this._moving =
false;
1646 this.
position( this._startPos.x +
x,
this._startPos.y +
y );
1664 var s={
x:
null,
y:
null}
1665 var n,p,dx,dy,adx,ady,sx,sy;
1668 function snapper(a,
x,
y)
1672 n = a[i].connectedNode();
1673 if (n && !n.selected)
1678 dx = p.x-(THIS._startPos.x+
x);
1679 dy = p.y-(THIS._startPos.y+
y);
1682 sx = p.x - THIS._startPos.x;
1683 sy = p.y - THIS._startPos.y;
1685 if ( (adx <= snapDistance) && (s.x===
null || sx < s.x) )
1690 if ( (ady <= snapDistance) && (s.y===
null || sy < s.y) )
1698 snapper(this._inputs,
x,
y);
1699 snapper(this._outputs,
x,
y);
1717 if (skipPlugs !==
true)
1719 for (var i in this._inputs)
1720 this._inputs[i].topStack();
1722 for (var o in this._outputs)
1723 this._outputs[o].topStack();
1726 var p = this._canvas._layers[this._layer];
1727 this._root.appendTo( p );
1740 for (var i in this._inputs) this._inputs[i].resetInvalid();
1741 for (var o in this._outputs) this._outputs[o].resetInvalid();
1761 var t = p.resolvedType();
1762 return (t==
"*") ? p.resolvedType(
true) : t;
1765 var _o = this._outputs;
1770 { nm = p._name+
"."+resType(p);
1772 if (!dest[nm]) dest[nm] = [];
1773 dest[nm].push( p.connectedPlug().path );
1779 var cnv = this._canvas._root;
1780 del.forEach(
function(c)
1782 var spath = c._source.path;
1783 var dpath = c._dest.path;
1784 var sig =
cable.connectID+
" "+spath.node+
"."+spath.plug+
" -> "+dpath.node+
"."+dpath.plug;
1785 var paths = {source:spath,dest:dpath};
1786 THIS._root.trigger(
"undoevent", {
1787 type:
"Remember Cable: "+sig,
1789 undo: cnv.trigger.bind(cnv,
"cableconnect",paths),
1790 redo: cnv.trigger.bind(cnv,
"cabledestroy",paths),
1838 get id() {
return this._attributes.uuid.value; },
1846 get name() {
return this._attributes.name.value; },
1854 set name(n) { this._attributes.name.value = n;
1856 this._label.text( n );
1868 get type() {
return this._type;
1877 set type(n) { this._type = n;
1879 this._title.text( n );
1889 get color() {
return this._attributes.node.value.color.value; },
1897 set color(c) { this._attributes.node.value.color.value = c;
1898 this._background.attr( {
1899 fill:
"#"+this._attributes.node.value.color.value,
1906 fill: (l > .6) ?
"#000000" :
"#FFFFFF",
1918 get x() {
return this._attributes.node.value.x.value; },
1926 get y() {
return this._attributes.node.value.y.value; },
1935 return this._selected;
1948 this._root.attr( {
"class":
"node node-selected"} );
1950 this._root.attr( {
"class":
"node"} );
1952 return this._selected;
1962 if (
"progress" in this._attributes)
1963 return this._attributes.progress.value;
1977 if (!(
"progress" in this._attributes))
1979 this._progress.attr({
1987 p = Math.min(100,Math.max(0,p));
1988 this._attributes.progress.value = p;
1992 var b = this._boundingBox;
1994 this._progress.attr({
2001 this._progress.attr({
2023 return (n.isChildOf(
this));
2042 for (var c in this._inputs)
applySubscription(data, metadata)
setter color
a setter DOCME
setter selected
a setter DOCME
cable(_cnv, _source, _dest, notrigger)
Javascript color object class.
setter value
a setter DOCME
getter id
returns the number of milliseconds since midnight January 1, 1970 UTC
boundsPosition(pt, labelPoint, dist)
getter position
A getter, returns this._position.
setter widget
a setter DOCME
getPlug(n, input, firstAvailable)
showPlugs()
show all hidden plugs, which would be split plugs that are not connected
node(_path, _cnv, _attrs, _in, _out, _base, _icon)
diffPosition(variable, value, widget)
baseValues(callback, definition)
return the values of this node that differ from the default value
hidePlugs()
show all hidden plugs, which would be split plugs that are not connected
isChildOf(_path, _cnv, _attrs, _in, _out)
setter name
a setter DOCME
setter type
a setter DOCME
applyDiff(id, diff, user, except)
registerObject(id, o, nosubscribe)
Register an object in the registry, and call the pathAddedCallback.
unregisterObject(id, o, silent, nounsubscribe, now)
Unregister an object from the registry.
attach()
Attach the tabs's children.
detach()
Detach the tab's children.
getter connected
a getter DOCME
getter type
a getter DOCME
plug(_node, _name, _isInput, _type)
getter mask
a getter DOCME
getter idle
a getter DOCME
applyRequestSuccess()
If an adminstrator has deleted his own preferences, this function will be called on success.
progress(c, t, f, w, hoc)
Utility functions for javascript clients.
keyCountFiltered(o, f)
Return the number of keys on an object that match a filter.
uuid()
Generate a universally unique identifier.
cleanPath(path)
Clean and normalize a resource path.
copyObject(source, dest)
Create a deep copy of a JSON object, extending the destination object recursively.
keyCount(o)
Return the number of keys in an object.
sortObjectByMemberAttribute(o, attr)
Sort an object by the value of an attribute of members of the object.
setAttr(e, a)
A DOM manipulation function to work around a jQuery bug.
extendBBox(b, a)
Extend bounding box b by an amount a.
isArray(a)
Determine if an object is a javascript array.
keyFromValue(o, val)
Given a value, retrieve the key for a potential entry in an object.