Remoto - VFS: backdrop.js Source File
Remoto - VFS
backdrop.js
Go to the documentation of this file.
1 
2 define( [
3  'remoto!stdlib:js/panes/panes/nodeCanvas/node.js',
4  'remoto!stdlib:js/include/utils.js',
5  'remoto!stdlib:js/include/color.js',
6  'remoto!stdlib:js/panes/panes/nodeCanvas/backdrop.css',
7  ],
8  function(node,utils,color)
9  {
10  'use strict';
11 
12  var svgns = "http://www.w3.org/2000/svg";
13 
34  backdrop.prototype = new node();
35 
36  var resizeSize = 5;
37 
38  function backdrop(_path,_cnv,_attrs,_inputs,_outputs,_base,_icon)
39  {
40  this._nodeClass = this._nodeClass || backdrop;
41 
42  this._notesWrapper = null;
43  this._notes = null;
44  this._header = null;
45  this._layer = "backdrop";
46 
47  this._resizers = {
48  TL: null,
49  TR: null,
50  BL: null,
51  BR: null
52  };
53 
54  node.call( this, _path, _cnv, _attrs, null, null, _base || "backdrop.rnd", _icon );
55  }
56 
65  backdrop.prototype.createSVG = function()
66  {
67  if (this._root) return;
68 
69  //var p = this._canvas._root;
70  var p = this._canvas._layers[this._layer];
71  var g = this._root = $( document.createElementNS(svgns,"g") ).appendTo(p).attr( { class:"node" } );
72  g.attr( { id: "node-backdrop" } );
73 
74  g.hide();
75 
76  g.attr( {
77  "vector-effect":"non-scaling-stroke",
78  //filter:"url(#dropShadow)",
79  } );
80 
81  var b = this._background = $( document.createElementNS(svgns,"rect") ).appendTo(g);
82 
83  b.attr( {
84  // rx:2,
85  // ry:2,
86  fill:"#"+this.color,
87  "vector-effect":"non-scaling-stroke",
88  //filter:"url(#dropShadow)",
89  "class":"nodeBackground node-backdrop",
90  //"mask":"url(#nodeGradientMask)",
91  "pointer-events": "none",
92  } );
93 
94  var h = this._header = $( document.createElementNS(svgns,"rect") ).appendTo(g);
95 
96  h.attr( {
97  fill:"#"+this.color,
98  "vector-effect":"non-scaling-stroke",
99  "class":"nodeHeader",
100  } );
101 
102  var l = this._label = $( document.createElementNS(svgns,"text") ).appendTo(g);
103 
104  l.text( this.name );
105 
106  l.attr( {
107  "class":"nodeLabel",
108  "text-anchor":"middle",
109  x:0,
110  y:11,
111  "font-size": 10,
112  } );
113 
114  var nw = this._notesWrapper = $( document.createElementNS(svgns,"foreignObject") ).appendTo(g);
115 
116  nw.attr( {
117  x:3,
118  y:15,
119  width:100,
120  height:100,
121  } );
122  nw.css( { "pointer-events": "none" } );
123 
124  var n = this._notes = $( "<div class='backdropText'>" ).appendTo(nw);
125  var t = this._attributes.notes.value;
126  n.text( t );
127 
128  var rc;
129  var rk = Object.keys(this._resizers);
130 
131  for (var rr=0,i=0; i<rk.length; rr+=90,i++)
132  {
133  rc = this._resizers[rk[i]] = $( document.createElementNS(svgns,"path") ).appendTo(g);
134  rc.attr( {
135  x: 0,
136  y: 0,
137  transform: "rotate("+rr+")",
138  d: "M0 "+resizeSize+"v-"+resizeSize+"h"+resizeSize,
139  "class": "resizeHandle",
140  } );
141 
142  rc.bind("mousedown", this.resizeCorner.bind(this,rk[i]));
143  }
144 
145  this.color = this.color;
146 
147  g.data("node",this);
148 
149  //this.initHandlers();
150  }
151 
162  backdrop.prototype.applyDiff = function(diff,user)
163  {
164  node.prototype.applyDiff.call(this,diff,user);
165 
166  this._diffing = true;
167 
168  if ("attributes" in diff)
169  {
170  var d = diff["attributes"];
171 
172  if ("box" in d)
173  this.resize();
174  }
175 
176  this._diffing = false;
177  }
178 
187  backdrop.prototype.resize = function()
188  {
189  this._root.show();
190 
191  var b = this._background;
192 
193  //console.log(this._attributes);
194 
195  var w = this._attributes.box.value.w.value;
196  var h = this._attributes.box.value.h.value;
197 
198  var a = {
199  x:0,
200  y:0,
201  width:w,
202  height:h,
203  };
204  b.attr(a);
205  this._boundingBox = a;
206 
207  var rr = this._resizers;
208  rr.TL.attr( { transform: "translate(0, 0) rotate(0) " } );
209  rr.TR.attr( { transform: "translate("+w+", 0) rotate(90) " } );
210  rr.BR.attr( { transform: "translate("+w+", "+h+") rotate(180) " } );
211  rr.BL.attr( { transform: "translate(0, "+h+") rotate(270) " } );
212 
213  var wr = this._notesWrapper;
214  var a2 = {
215  x:3,
216  y:15,
217  width:Math.max(w-6,0),
218  height:Math.max(h-18,0),
219  };
220  wr.attr(a2);
221 
222  var hd = this._header;
223  var ha = {
224  x:0,
225  y:0,
226  width: w,
227  height: 14,
228  }
229  hd.attr(ha);
230 
231  this._label.attr( { x:w/2 } );
232 
233  var ns = this._attributes.font.value.size.value;
234  var nc = this._attributes.font.value.color.value;
235  var ff = this._attributes.fontface.value;
236  this._notes.css( {
237  "font-family": ff,
238  "font-size": ns+"px",
239  "line-height": (ns+4)+"px",
240  "color": "#"+nc,
241  } );
242  }
243 
254  backdrop.prototype.resizeCorner = function(which,evt)
255  {
256  //console.log("resize corner",arguments);
257  //return false;
258 
259  //FIXME make sure undo is in here
260 
261  var THIS = this;
262  var pos = this.position();
263  var body = $("body");
264  var doc = $(document);
265  var x=0,y=0,moved = false;
266  var mw = this._attributes.box.value.w.value;
267  var mh = this._attributes.box.value.h.value;
268  var mx,my;
269  var b = { w:{value:mw}, h:{value:mh} };
270 
271  var v = which[0] === "T"; //top or bottom?
272  var h = which[1] === "L"; //left or right?
273 
274  var click = {
275  cx:evt.clientX,
276  cy:evt.clientY,
277  };
278 
279  function mm(e)
280  {
281  if (!moved)
282  { moved = true;
283  THIS.startMove();
284  body.css("cursor","pointer");
285  }
286 
287  x = e.clientX - click.cx;
288  y = e.clientY - click.cy;
289 
290  x /= THIS._canvas._zoom;
291  y /= THIS._canvas._zoom;
292 
293  //console.log(x,y,e,click);
294 
295  if (v)
296  {
297  my = y;
298  b.h.value = mh-y;
299  }
300  else
301  { my = 0;
302  b.h.value = mh+y;
303  }
304 
305  if (b.h.value < 0)
306  {
307  my = b.h.value;
308  b.h.value = Math.abs(b.h.value);
309  }
310 
311  if (h)
312  {
313  mx = x;
314  b.w.value = mw-x;
315  }
316  else
317  { mx = 0;
318  b.w.value = mw+x;
319  }
320 
321  if (b.w.value < 0)
322  {
323  mx = b.w.value;
324  b.w.value = Math.abs(b.w.value);
325  }
326 
327  //console.log(mx,my,b.w,b.h);
328  THIS.moveBy(mx,my);
329  THIS._attributes.box.immediateValue = b;
330 
331  THIS.resize();
332 
333  return false;
334  }
335  doc.bind("mousemove", mm);
336 
337  function mu(e)
338  {
339  doc.unbind("mouseup",mu);
340  doc.unbind("mousemove",mm);
341  body.css("cursor","");
342 
343  THIS.stopMove();
344  }
345  doc.bind("mouseup", mu);
346 
347  return false;
348  }
349 
358  backdrop.prototype.encompassedNodes = function()
359  {
360  var c = this._canvas;
361  var b = this._background[0].getBBox();
362  b.x = c._x + this.x*c._zoom;
363  b.y = c._y + this.y*c._zoom;
364  b.width *= c._zoom;
365  b.height *= c._zoom;
366  //console.log(b);
367 
368  var rr = this._canvas._root[0].ownerSVGElement;
369  //var c = rr.getIntersectionList(b,null);
370  var c = rr.getEnclosureList(b,null);
371  var n,l = {};
372 
373  for (var i=0;i<c.length;i++)
374  {
375  //if (c[i] != b[0]) //ignore the selection box itself
376  if (c[i].classList.contains("nodeBackground")) //only capture the node backgrounds, not cables, plugs or selection box
377  {
378  n = $( c[i].parentNode ).data("node");
379  l[n.id] = n;
380  }
381  }
382 
383  return l;
384  }
385 
394  backdrop.prototype.isEmpty = function()
395  {
396  var l = this.encompassedNodes();
397 
398  return (Object.keys(l).length === 0);
399  }
400 
401 
413  backdrop.prototype.__defineSetter__("color", function(c)
414  {
415  this._attributes.node.value.color.value = c;
416  this._background.attr( {
417  fill:"#"+c,
418  stroke:"#"+c,
419  } );
420 
421  this._header.attr( {
422  fill:"#"+c,
423  } );
424 
425  var rc,rk = Object.keys(this._resizers);
426  for (var i=0; i<rk.length; i++)
427  {
428  rc = this._resizers[rk[i]];
429  rc.attr( {
430  stroke: "#"+c
431  } );
432  }
433 
434  var l = color.fromHTML(c).luminance;
435 
436  if (this._label)
437  this._label.css( {
438  fill: (l > .6) ? "#000000" : "#FFFFFF",
439  } );
440  } );
441 
448  backdrop.prototype.__defineGetter__("color", function()
449  {
450  return this._attributes.node.value.color.value;
451  } );
452 
459  backdrop.prototype.__defineSetter__("notes", function(n)
460  {
461  this._attributes.notes.value = n;
462 
463  this._notes.text(n);
464  } );
465 
472  backdrop.prototype.__defineGetter__("notes", function()
473  {
474  return this._attributes.notes.value;
475  } );
476 
483  backdrop.prototype.__defineSetter__("font", function(f)
484  {
485  //console.log("set font:",f);
486 
487  this._attributes.font.value = f;
488 
489  this.resize();
490  } );
491 
498  backdrop.prototype.__defineGetter__("font", function()
499  {
500  return this._attributes.font.value;
501  } );
502 
509  backdrop.prototype.__defineSetter__("fontface", function(f)
510  {
511  //console.log("set font:",f);
512 
513  this._attributes.fontface.value = f;
514 
515  this.resize();
516  } );
517 
524  backdrop.prototype.__defineGetter__("fontface", function()
525  {
526  return this._attributes.fontface.value;
527  } );
528 
535  backdrop.prototype.__defineSetter__("selected", function(s)
536  {
537  if (s === this._selected)
538  return;
539 
540  this._selected = s;
541 
542  if (s)
543  this._root.attr( {"class":"node node-selected"} );
544  else
545  this._root.attr( {"class":"node"} );
546 
547  var l = this.encompassedNodes();
548  l[this.id] = this;
549 
550  for (var n in l)
551  l[n].selected = s;
552 
553  return this._selected;
554  } );
555 
562  backdrop.prototype.__defineGetter__("selected", function()
563  {
564  return this._selected;
565  } );
566 
567 
570  return backdrop;
571  }
572 );
backdrop(_path, _cnv, _attrs, _icon)
setter color
a setter DOCME
encompassedNodes()
returns the list of nodes encompassed by this backdrop
applyDiff(diff, user)
isEmpty()
returns boolean if this backdrop is empty.
resizeCorner(which, event)
Javascript color object class.
fromHTML(html)
getter luminance
a getter DOCME
setter value
a setter DOCME
getter id
returns the number of milliseconds since midnight January 1, 1970 UTC
setter user
a setter DOCME
getter position
A getter, returns this._position.
transform(x, y, z)
node(_path, _cnv, _attrs, _in, _out, _base, _icon)
getter x
a getter DOCME
getter y
a getter DOCME
applyDiff(diff, user)
setter name
a setter DOCME
resize()
Does nothing.
Utility functions for javascript clients.