client/js/paper-renderer.js
changeset 132 860340d4c645
parent 122 ea11e17e0a35
child 152 5306bf5284c2
child 168 f978d70a9e63
equal deleted inserted replaced
122:ea11e17e0a35 132:860340d4c645
     1 Rkns.Renderer = {
     1 Rkns.Renderer = {
     2     _MINIMAP_MARGIN: 20,
     2     _MINIMAP_MARGIN: 20,
     3     _MIN_DRAG_DISTANCE: 2,
     3     _MIN_DRAG_DISTANCE: 2,
     4     _NODE_SIZE_BASE: 25,
       
     5     _NODE_BUTTON_WIDTH: 40,
     4     _NODE_BUTTON_WIDTH: 40,
     6     _EDGE_BUTTON_INNER: 2,
     5     _EDGE_BUTTON_INNER: 2,
     7     _EDGE_BUTTON_OUTER: 40,
     6     _EDGE_BUTTON_OUTER: 40,
     8     _CLICKMODE_ADDNODE : 1,
     7     _CLICKMODE_ADDNODE : 1,
     9     _CLICKMODE_STARTEDGE : 2,
     8     _CLICKMODE_STARTEDGE : 2,
    11     _IMAGE_MAX_KB : 500,
    10     _IMAGE_MAX_KB : 500,
    12     _NODE_SIZE_STEP: Math.LN2/4,
    11     _NODE_SIZE_STEP: Math.LN2/4,
    13     _MIN_SCALE: 1/20,
    12     _MIN_SCALE: 1/20,
    14     _MAX_SCALE: 20,
    13     _MAX_SCALE: 20,
    15     _AUTOSCALE_MARGIN: 50,
    14     _AUTOSCALE_MARGIN: 50,
    16     _USER_PLACEHOLDER : {
    15     _USER_PLACEHOLDER : function(_renkan) {
    17         color: "#000000",
    16     	return {
    18         title: "(unknown user)",
    17     		color: _renkan.options.default_user_color,
    19         get: function(attr) {
    18 	        title: _renkan.translate("(unknown user)"),
    20             return this[attr] || false;
    19 	        get: function(attr) {
    21         }
    20 	            return this[attr] || false;
       
    21 	        }
       
    22     	}
    22     },
    23     },
    23     _BOOKMARKLET_CODE: function(_renkan) {
    24     _BOOKMARKLET_CODE: function(_renkan) {
    24     	return "(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\">"
    25     	return "(function(a,b,c,d,e,f,h,i,j,k,l,m,n,o,p,q,r){a=document;b=a.body;c=a.location.href;j='draggable';m='text/x-iri-';d=a.createElement('div');d.innerHTML='<p_style=\"position:fixed;top:0;right:0;font:bold_18px_sans-serif;color:#fff;background:#909;padding:10px;z-index:100000;\">"
    25 	    + _renkan.translate("Drag items from this website, drop them in Renkan").replace(/ /g,"_")
    26 	    + _renkan.translate("Drag items from this website, drop them in Renkan").replace(/ /g,"_")
    26 	    + "</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\/\\/[^\\/]*twitter\\.com\\//,s:'.tweet',n:'twitter'},{r:/https?:\\/\\/[^\\/]*google\\.[^\\/]+\\//,s:'.g',n:'google'},{r:/https?:\\/\\/[^\\/]*lemonde\\.fr\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();"
    27 	    + "</p>'.replace(/_/g,String.fromCharCode(32));b.appendChild(d);e=[{r:/https?:\\/\\/[^\\/]*twitter\\.com\\//,s:'.tweet',n:'twitter'},{r:/https?:\\/\\/[^\\/]*google\\.[^\\/]+\\//,s:'.g',n:'google'},{r:/https?:\\/\\/[^\\/]*lemonde\\.fr\\//,s:'[data-vr-contentbox]',n:'lemonde'}];f=false;e.forEach(function(g){if(g.r.test(c)){f=g;}});if(f){h=function(){Array.prototype.forEach.call(a.querySelectorAll(f.s),function(i){i[j]=true;k=i.style;k.borderWidth='2px';k.borderColor='#909';k.borderStyle='solid';k.backgroundColor='rgba(200,0,180,.1)';})};window.setInterval(h,500);h();};a.addEventListener('dragstart',function(k){l=k.dataTransfer;l.setData(m+'source-uri',c);l.setData(m+'source-title',a.title);n=k.target;if(f){o=n;while(!o.attributes[j]){o=o.parentNode;if(o==b){break;}}}if(f&&o.attributes[j]){p=o.cloneNode(true);l.setData(m+'specific-site',f.n)}else{q=a.getSelection();if(q.type==='Range'||!q.type){p=q.getRangeAt(0).cloneContents();}else{p=n.cloneNode();}}r=a.createElement('div');r.appendChild(p);l.setData('text/x-iri-selected-text',r.textContent.trim());l.setData('text/x-iri-selected-html',r.innerHTML);},false);})();"
    78         var _options = _repr.renderer.renkan.options,
    79         var _options = _repr.renderer.renkan.options,
    79         	_startRads = _startAngle * Math.PI / 180,
    80         	_startRads = _startAngle * Math.PI / 180,
    80             _endRads = _endAngle * Math.PI / 180,
    81             _endRads = _endAngle * Math.PI / 180,
    81             _img = new Image(),
    82             _img = new Image(),
    82             _span = _endRads - _startRads,
    83             _span = _endRads - _startRads,
    83             _k = .0879 * _span,
       
    84             _kin = _k * _inR,
       
    85             _kout = _k * _outR,
       
    86             _startdx = - Math.sin(_startRads),
    84             _startdx = - Math.sin(_startRads),
    87             _startdy = Math.cos(_startRads),
    85             _startdy = Math.cos(_startRads),
    88             _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx,
    86             _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx,
    89             _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy,
    87             _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy,
    90             _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx,
    88             _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx,
   102             _centerXIn = Math.cos(_centerRads) * _inR,
   100             _centerXIn = Math.cos(_centerRads) * _inR,
   103             _centerXOut = Math.cos(_centerRads) * _outR,
   101             _centerXOut = Math.cos(_centerRads) * _outR,
   104             _centerYIn = Math.sin(_centerRads) * _inR,
   102             _centerYIn = Math.sin(_centerRads) * _inR,
   105             _centerYOut = Math.sin(_centerRads) * _outR,
   103             _centerYOut = Math.sin(_centerRads) * _outR,
   106             _textX = Math.cos(_centerRads) * (_outR + 3),
   104             _textX = Math.cos(_centerRads) * (_outR + 3),
   107             _textY = Math.sin(_centerRads) * (_outR + 3),
   105             _textY = Math.sin(_centerRads) * (_outR + _options.buttons_label_font_size) + _options.buttons_label_font_size / 2,
   108             _segments = [];
   106             _segments = [];
   109     	_repr.renderer.buttons_layer.activate();
   107     	_repr.renderer.buttons_layer.activate();
   110         var _path = new paper.Path();
   108         var _path = new paper.Path();
   111         _path.add([_startXIn, _startYIn]);
   109         _path.add([_startXIn, _startYIn]);
   112         _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);
   110         _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);
   114         _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);
   112         _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);
   115         _path.fillColor = _options.buttons_background;
   113         _path.fillColor = _options.buttons_background;
   116         _path.opacity = .5;
   114         _path.opacity = .5;
   117         _path.closed = true;
   115         _path.closed = true;
   118         _path.__representation = _repr;
   116         _path.__representation = _repr;
   119         if (_textX >= -2 && _textX <= 2) {
       
   120             if (_textY > 0) {
       
   121                 _textY += 6;
       
   122             }
       
   123         }
       
   124         var _text = new paper.PointText(_textX,_textY);
   117         var _text = new paper.PointText(_textX,_textY);
   125         _text.characterStyle = {
   118         _text.characterStyle = {
   126             fontSize: _options.buttons_label_font_size,
   119             fontSize: _options.buttons_label_font_size,
   127             fillColor: _options.buttons_label_color
   120             fillColor: _options.buttons_label_color
   128         };
   121         };
   184 }
   177 }
   185 
   178 
   186 Rkns.Renderer._BaseRepresentation = function(_renderer, _model) {
   179 Rkns.Renderer._BaseRepresentation = function(_renderer, _model) {
   187     if (typeof _renderer !== "undefined") {
   180     if (typeof _renderer !== "undefined") {
   188         this.renderer = _renderer;
   181         this.renderer = _renderer;
       
   182         this.renkan = _renderer.renkan;
   189         this.project = _renderer.renkan.project;
   183         this.project = _renderer.renkan.project;
       
   184         this.options = _renderer.renkan.options;
   190         this.model = _model;
   185         this.model = _model;
   191         if (this.model) {
   186         if (this.model) {
   192             var _this = this;
   187             var _this = this;
   193             this._changeBinding = function() {
   188             this._changeBinding = function() {
   194                 _this.redraw();
   189                 _this.redraw();
   232         this.model.off("change", this._changeBinding );
   227         this.model.off("change", this._changeBinding );
   233         this.model.off("remove", this._removeBinding );
   228         this.model.off("remove", this._removeBinding );
   234     }
   229     }
   235 }
   230 }
   236 
   231 
       
   232 /* */
       
   233 
       
   234 Rkns.Renderer._BaseButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
       
   235 
       
   236 Rkns.Renderer._BaseButton.prototype.moveTo = function(_pos) {
       
   237     this.sector.moveTo(_pos);
       
   238 }
       
   239 
       
   240 Rkns.Renderer._BaseButton.prototype.show = function() {
       
   241     this.sector.show();
       
   242 }
       
   243 
       
   244 Rkns.Renderer._BaseButton.prototype.hide = function() {
       
   245     this.sector.hide();
       
   246 }
       
   247 
       
   248 Rkns.Renderer._BaseButton.prototype.select = function() {
       
   249     this.sector.select();
       
   250 }
       
   251 
       
   252 Rkns.Renderer._BaseButton.prototype.unselect = function(_newTarget) {
       
   253     this.sector.unselect();
       
   254     if (!_newTarget || (_newTarget !== this.source_representation && _newTarget.source_representation !== this.source_representation)) {
       
   255         this.source_representation.unselect();
       
   256     }
       
   257 }
       
   258 
       
   259 Rkns.Renderer._BaseButton.prototype.destroy = function() {
       
   260     this.sector.destroy();
       
   261 }
       
   262 
       
   263 /* */
       
   264 
   237 Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   265 Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   238 
   266 
   239 Rkns.Renderer.Node.prototype._init = function() {
   267 Rkns.Renderer.Node.prototype._init = function() {
   240     this.renderer.node_layer.activate();
   268     this.renderer.node_layer.activate();
   241     this.type = "Node";
   269     this.type = "Node";
   242     this.circle = new paper.Path.Circle([0, 0], 1);
   270     this.circle = new paper.Path.Circle([0, 0], 1);
   243     this.circle.__representation = this;
   271     this.circle.__representation = this;
   244     this.circle.fillColor = '#ffffff';
   272     this.circle.fillColor = this.options.node_fill_color;
   245     if (this.renderer.renkan.options.show_node_circles) {
   273     if (this.options.show_node_circles) {
   246 	    this.circle.strokeWidth = this.renderer.renkan.options.node_stroke_width;
   274 	    this.circle.strokeWidth = this.options.node_stroke_width;
   247 	    this.h_ratio = 1;
   275 	    this.h_ratio = 1;
   248     } else {
   276     } else {
   249     	this.circle.opacity = .01;
   277     	this.circle.opacity = .01;
   250     	this.h_ratio = 0;
   278     	this.h_ratio = 0;
   251     }
   279     }
   252     this.title = new paper.PointText([0,0]);
   280     this.title = new paper.PointText([0,0]);
   253     this.title.characterStyle = {
   281     this.title.characterStyle = {
   254         font: this.renderer.renkan.options.node_label_font,
   282         font: this.options.node_label_font,
   255         fontSize: this.renderer.renkan.options.node_label_font_size,
   283         fontSize: this.options.node_label_font_size,
   256         fillColor: this.renderer.renkan.options.node_label_color
   284         fillColor: this.options.node_label_color
   257     };
   285     };
   258     if (this.renderer.renkan.options.editor_mode) {
   286     if (this.options.editor_mode) {
   259         this.edit_button = new Rkns.Renderer.NodeEditButton(this.renderer, null);
   287     	this.buttons = [
   260         this.edit_button.node_representation = this;
   288     		new Rkns.Renderer.NodeEditButton(this.renderer, null),
   261         this.remove_button = new Rkns.Renderer.NodeRemoveButton(this.renderer, null);
   289     		new Rkns.Renderer.NodeRemoveButton(this.renderer, null),
   262         this.remove_button.node_representation = this;
   290     		new Rkns.Renderer.NodeLinkButton(this.renderer, null),
   263         this.link_button = new Rkns.Renderer.NodeLinkButton(this.renderer, null);
   291     		new Rkns.Renderer.NodeEnlargeButton(this.renderer, null),
   264         this.link_button.node_representation = this;
   292     		new Rkns.Renderer.NodeShrinkButton(this.renderer, null)
       
   293     	];
       
   294     	for (var i = 0; i < this.buttons.length; i++) {
       
   295     		this.buttons[i].source_representation = this;
       
   296     	}
       
   297     } else {
       
   298     	this.buttons = [];
   265     }
   299     }
   266     this.last_circle_radius = 1;
   300     this.last_circle_radius = 1;
   267     this.title.paragraphStyle.justification = 'center';
   301     this.title.paragraphStyle.justification = 'center';
   268     
   302     
   269     if (this.renderer.minimap) {
   303     if (this.renderer.minimap) {
   273     }
   307     }
   274 }
   308 }
   275 
   309 
   276 Rkns.Renderer.Node.prototype.redraw = function(_dontRedrawEdges) {
   310 Rkns.Renderer.Node.prototype.redraw = function(_dontRedrawEdges) {
   277     var _model_coords = new paper.Point(this.model.get("position")),
   311     var _model_coords = new paper.Point(this.model.get("position")),
   278     	_baseRadius = Rkns.Renderer._NODE_SIZE_BASE * Math.exp((this.model.get("size") || 0) * Rkns.Renderer._NODE_SIZE_STEP);
   312     	_baseRadius = this.options.node_size_base * Math.exp((this.model.get("size") || 0) * Rkns.Renderer._NODE_SIZE_STEP);
   279     if (!this.is_dragging || !this.paper_coords) {
   313     if (!this.is_dragging || !this.paper_coords) {
   280         this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   314         this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   281     }
   315     }
   282     this.circle_radius = _baseRadius * this.renderer.scale;
   316     this.circle_radius = _baseRadius * this.renderer.scale;
   283     if (this.last_circle_radius !== this.circle_radius) {
   317     if (this.last_circle_radius !== this.circle_radius) {
   284     	if (this.renderer.renkan.options.editor_mode) {
   318     	this.buttons.forEach(function(b) {
   285 	    	this.edit_button.setSectorSize();
   319     		b.setSectorSize();
   286 	    	this.remove_button.setSectorSize();
   320     	});
   287 	    	this.link_button.setSectorSize();
       
   288 	    }
       
   289 	    var square = new paper.Size(this.circle_radius, this.circle_radius),
   321 	    var square = new paper.Size(this.circle_radius, this.circle_radius),
   290 	    	topleft = this.paper_coords.subtract(square),
   322 	    	topleft = this.paper_coords.subtract(square),
   291 	    	bounds = new paper.Rectangle(topleft, square.multiply(2));
   323 	    	bounds = new paper.Rectangle(topleft, square.multiply(2));
   292     	this.circle.fitBounds(bounds);
   324     	this.circle.fitBounds(bounds);
   293 	    if (this.node_image) {
   325 	    if (this.node_image) {
   299             this.node_image.position = this.paper_coords;
   331             this.node_image.position = this.paper_coords;
   300         }
   332         }
   301     }
   333     }
   302     this.last_circle_radius = this.circle_radius;
   334     this.last_circle_radius = this.circle_radius;
   303     
   335     
   304     var _text = this.model.get("title") || this.renderer.renkan.translate("(untitled)");
   336     var _text = this.model.get("title") || this.renkan.translate("(untitled)");
   305     this.title.content = Rkns.Renderer.Utils.shortenText(_text, this.renderer.renkan.options.node_label_max_length);
   337     this.title.content = Rkns.Renderer.Utils.shortenText(_text, this.options.node_label_max_length);
   306 
   338 
   307     this.title.position = this.paper_coords.add([
   339     this.title.position = this.paper_coords.add([
   308     	0,
   340     	0,
   309     	this.circle_radius * this.h_ratio + this.renderer.renkan.options.node_label_font_size + this.renderer.renkan.options.node_label_distance
   341     	this.circle_radius * this.h_ratio + this.options.node_label_font_size + this.options.node_label_distance
   310 	]);
   342 	]);
   311     var _color = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color");
   343     var _color = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color");
   312     this.circle.strokeColor = _color;
   344     this.circle.strokeColor = _color;
   313     if (this.renderer.renkan.options.editor_mode) {
   345     var _pc = this.paper_coords;
   314     	this.edit_button.moveTo(this.paper_coords);
   346 	this.buttons.forEach(function(b) {
   315 	    this.remove_button.moveTo(this.paper_coords);
   347 		b.moveTo(_pc);
   316 	    this.link_button.moveTo(this.paper_coords);
   348 	});
   317     }
       
   318     var _img = this.model.get("image");
   349     var _img = this.model.get("image");
   319     if (_img && _img !== this.img) {
   350     if (_img && _img !== this.img) {
   320         var _image = new Image(),
   351         var _image = new Image(),
   321             _this = this;
   352             _this = this;
   322         _image.onload = function() {
   353         _image.onload = function() {
   323             if (_this.node_image) {
   354             if (_this.node_image) {
   324                 _this.node_image.remove();
   355                 _this.node_image.remove();
   325             }
   356             }
   326             _this.renderer.node_layer.activate();
   357             _this.renderer.node_layer.activate();
   327             var _ratio = Math.min(2 / _image.width, 2 / _image.height );
   358             var _ratio = Math.min(2 / _image.width, 2 / _image.height );
   328             if (!_this.renderer.renkan.options.show_node_circles) {
   359             if (!_this.options.show_node_circles) {
   329             	_this.h_ratio = Math.min(1, _image.height / _image.width);
   360             	_this.h_ratio = Math.min(1, _image.height / _image.width);
   330             }
   361             }
   331             var _raster = new paper.Raster(_image);
   362             var _raster = new paper.Raster(_image);
   332             if (_this.renderer.renkan.options.clip_node_images) {
   363             if (_this.options.clip_node_images) {
   333 	            var _clip = new paper.Path.Circle([0, 0], 1);
   364 	            var _clip = new paper.Path.Circle([0, 0], 1);
   334 	            _raster.scale(_ratio);
   365 	            _raster.scale(_ratio);
   335 	            _this.node_image = new paper.Group(_clip, _raster);
   366 	            _this.node_image = new paper.Group(_clip, _raster);
   336 	            _this.node_image.opacity = .99;
   367 	            _this.node_image.opacity = .99;
   337 	            /* This is a workaround to allow clipping at group level
   368 	            /* This is a workaround to allow clipping at group level
   346 		    var square = new paper.Size(_this.circle_radius, _this.circle_radius),
   377 		    var square = new paper.Size(_this.circle_radius, _this.circle_radius),
   347 		    	topleft = _this.paper_coords.subtract(square),
   378 		    	topleft = _this.paper_coords.subtract(square),
   348 		    	bounds = new paper.Rectangle(topleft, square.multiply(2));
   379 		    	bounds = new paper.Rectangle(topleft, square.multiply(2));
   349 		    _this.node_image.fitBounds(bounds);
   380 		    _this.node_image.fitBounds(bounds);
   350             _this.redraw();
   381             _this.redraw();
       
   382     		paper.view.draw();
   351         }
   383         }
   352         _image.src = _img;
   384         _image.src = _img;
   353     }
   385     }
   354     this.img = _img;
   386     this.img = _img;
   355     if (this.node_image && !this.img) {
   387     if (this.node_image && !this.img) {
   375     }
   407     }
   376 
   408 
   377 }
   409 }
   378 
   410 
   379 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   411 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   380 	if (this.renderer.renkan.options.editor_mode) {
   412 	if (this.options.editor_mode) {
   381 		if (!this.renderer.renkan.read_only) {
   413 		if (!this.renkan.read_only) {
   382 			this.is_dragging = true;
   414 			this.is_dragging = true;
   383 			this.paper_coords = this.paper_coords.add(_delta);
   415 			this.paper_coords = this.paper_coords.add(_delta);
   384 	    	this.redraw();
   416 	    	this.redraw();
   385     	}
   417     	}
   386 	} else {
   418 	} else {
   389 }
   421 }
   390 
   422 
   391 Rkns.Renderer.Node.prototype.openEditor = function() {
   423 Rkns.Renderer.Node.prototype.openEditor = function() {
   392     this.renderer.removeRepresentationsOfType("editor");
   424     this.renderer.removeRepresentationsOfType("editor");
   393     var _editor = this.renderer.addRepresentation("NodeEditor",null);
   425     var _editor = this.renderer.addRepresentation("NodeEditor",null);
   394     _editor.node_representation = this;
   426     _editor.source_representation = this;
   395     _editor.draw();
   427     _editor.draw();
   396 }
   428 }
   397 
   429 
   398 Rkns.Renderer.Node.prototype.select = function() {
   430 Rkns.Renderer.Node.prototype.select = function() {
   399     this.circle.strokeWidth = this.renderer.renkan.options.selected_node_stroke_width;
   431     this.circle.strokeWidth = this.options.selected_node_stroke_width;
   400     if (this.renderer.isEditable()) {
   432     if (this.renderer.isEditable()) {
   401 	    this.edit_button.show();
   433     	this.buttons.forEach(function(b) {
   402 	    this.remove_button.show();
   434     		b.show();
   403 	    this.link_button.show();
   435     	});
   404     }
   436     }
   405     var _uri = this.model.get("uri");
   437     var _uri = this.model.get("uri");
   406     if (_uri) {
   438     if (_uri) {
   407     	Rkns.$('.Rk-Bin-Item').each(function() {
   439     	Rkns.$('.Rk-Bin-Item').each(function() {
   408 	        var _el = Rkns.$(this);
   440 	        var _el = Rkns.$(this);
   409 	        if (_el.attr("data-uri") == _uri) {
   441 	        if (_el.attr("data-uri") == _uri) {
   410 	            _el.addClass("selected");
   442 	            _el.addClass("selected");
   411 	        }
   443 	        }
   412 	    });
   444 	    });
   413     }
   445     }
   414     if (!this.renderer.renkan.options.editor_mode) {
   446     if (!this.options.editor_mode) {
   415         this.openEditor();
   447         this.openEditor();
   416     }
   448     }
   417     
   449     
   418     if (this.renderer.minimap) {
   450     if (this.renderer.minimap) {
   419     	this.minimap_circle.fillColor = "#ff00fc";
   451 		this.minimap_circle.strokeWidth = this.options.minimap_highlight_weight;
       
   452     	this.minimap_circle.strokeColor = this.options.minimap_highlight_color;
   420     }
   453     }
   421 }
   454 }
   422 
   455 
   423 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
   456 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
   424     if (!_newTarget || _newTarget.node_representation !== this) {
   457     if (!_newTarget || _newTarget.source_representation !== this) {
   425 	    if (this.renderer.renkan.options.editor_mode) {
   458     	this.buttons.forEach(function(b) {
   426 	        this.edit_button.hide();
   459     		b.hide();
   427 	        this.remove_button.hide();
   460     	});
   428 	        this.link_button.hide();
   461     	this.circle.strokeWidth = this.options.node_stroke_width;
   429 	   	}
       
   430     	this.circle.strokeWidth = this.renderer.renkan.options.node_stroke_width;
       
   431         Rkns.$('.Rk-Bin-Item').removeClass("selected");
   462         Rkns.$('.Rk-Bin-Item').removeClass("selected");
   432     	if (this.renderer.minimap) {
   463     	if (this.renderer.minimap) {
   433     		this.minimap_circle.fillColor = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color");
   464     		this.minimap_circle.strokeColor = undefined;
   434     	}
   465     	}
   435     }
   466     }
   436 }
   467 }
   437 
   468 
   438 Rkns.Renderer.Node.prototype.highlight = function() {
   469 Rkns.Renderer.Node.prototype.highlight = function() {
   439     this.circle.fillColor = "#ffff80";
   470     this.circle.fillColor = this.options.highlighted_node_fill_color;
   440     if (this.node_image) {
   471     if (this.node_image) {
   441         this.node_image.opacity = .5;
   472         this.node_image.opacity = .5;
   442     }
   473     }
   443 }
   474 }
   444 
   475 
   445 Rkns.Renderer.Node.prototype.unhighlight = function(_newTarget) {
   476 Rkns.Renderer.Node.prototype.unhighlight = function(_newTarget) {
   446     this.circle.fillColor = "#ffffff";
   477     this.circle.fillColor = this.options.node_fill_color;
   447     if (this.node_image) {
   478     if (this.node_image) {
   448         this.node_image.opacity = .99;
   479         this.node_image.opacity = .99;
   449     }
   480     }
   450 }
   481 }
   451 
   482 
   474     this.is_dragging = false;
   505     this.is_dragging = false;
   475 }
   506 }
   476 
   507 
   477 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   508 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   478     this.super("destroy");
   509     this.super("destroy");
   479     if (this.renderer.renkan.options.editor_mode) {
   510 	this.buttons.forEach(function(b) {
   480 	    this.edit_button.destroy();
   511 		b.destroy();
   481 	    this.remove_button.destroy();
   512 	});
   482 	    this.link_button.destroy();
       
   483     }
       
   484     this.circle.remove();
   513     this.circle.remove();
   485     this.title.remove();
   514     this.title.remove();
   486     if (this.renderer.minimap) {
   515     if (this.renderer.minimap) {
   487     	this.minimap_circle.remove();
   516     	this.minimap_circle.remove();
   488     }
   517     }
   502     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
   531     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
   503     this.bundle = this.renderer.addToBundles(this);
   532     this.bundle = this.renderer.addToBundles(this);
   504     this.line = new paper.Path();
   533     this.line = new paper.Path();
   505     this.line.add([0,0],[0,0],[0,0]);
   534     this.line.add([0,0],[0,0],[0,0]);
   506     this.line.__representation = this;
   535     this.line.__representation = this;
   507     this.line.strokeWidth = this.renderer.renkan.options.edge_stroke_width;
   536     this.line.strokeWidth = this.options.edge_stroke_width;
   508     this.arrow = new paper.Path();
   537     this.arrow = new paper.Path();
   509     this.arrow.add(
   538     this.arrow.add(
   510     	[ 0, 0 ],
   539     	[ 0, 0 ],
   511     	[ this.renderer.renkan.options.edge_arrow_length, this.renderer.renkan.options.edge_arrow_width / 2 ],
   540     	[ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],
   512     	[ 0, this.renderer.renkan.options.edge_arrow_width ]
   541     	[ 0, this.options.edge_arrow_width ]
   513 	);
   542 	);
   514     this.arrow.__representation = this;
   543     this.arrow.__representation = this;
   515     this.text = new paper.PointText();
   544     this.text = new paper.PointText();
   516     this.text.characterStyle = {
   545     this.text.characterStyle = {
   517         font: this.renderer.renkan.options.edge_label_font,
   546         font: this.options.edge_label_font,
   518         fontSize: this.renderer.renkan.options.edge_label_font_size,
   547         fontSize: this.options.edge_label_font_size,
   519         fillColor: this.renderer.renkan.options.edge_label_color
   548         fillColor: this.options.edge_label_color
   520     };
   549     };
   521     this.text.paragraphStyle.justification = 'center';
   550     this.text.paragraphStyle.justification = 'center';
   522     this.text_angle = 0;
   551     this.text_angle = 0;
   523     this.arrow_angle = 0;
   552     this.arrow_angle = 0;
   524     if (this.renderer.renkan.options.editor_mode) {
   553     if (this.options.editor_mode) {
   525         this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null);
   554         this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null);
   526         this.edit_button.edge_representation = this;
   555         this.edit_button.source_representation = this;
   527         this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null);
   556         this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null);
   528         this.remove_button.edge_representation = this;
   557         this.remove_button.source_representation = this;
   529     }
   558     }
   530     
   559     
   531     if (this.renderer.minimap) {
   560     if (this.renderer.minimap) {
   532     	this.renderer.minimap.edge_layer.activate();
   561     	this.renderer.minimap.edge_layer.activate();
   533 	    this.minimap_line = new paper.Path();
   562 	    this.minimap_line = new paper.Path();
   547         _v = _p1a.subtract(_p0a),
   576         _v = _p1a.subtract(_p0a),
   548         _r = _v.length,
   577         _r = _v.length,
   549         _u = _v.divide(_r),
   578         _u = _v.divide(_r),
   550         _ortho = new paper.Point([- _u.y, _u.x]),
   579         _ortho = new paper.Point([- _u.y, _u.x]),
   551         _group_pos = this.bundle.getPosition(this),
   580         _group_pos = this.bundle.getPosition(this),
   552         _delta = _ortho.multiply( this.renderer.renkan.options.edge_gap_in_bundles * _group_pos ),
   581         _delta = _ortho.multiply( this.options.edge_gap_in_bundles * _group_pos ),
   553         _p0b = _p0a.add(_delta), /* Adding a 4 px difference */
   582         _p0b = _p0a.add(_delta), /* Adding a 4 px difference */
   554         _p1b = _p1a.add(_delta), /* to differentiate bundled links */
   583         _p1b = _p1a.add(_delta), /* to differentiate bundled links */
   555         _a = _v.angle,
   584         _a = _v.angle,
   556         _textdelta = _ortho.multiply(this.renderer.renkan.options.edge_label_distance),
   585         _textdelta = _ortho.multiply(this.options.edge_label_distance),
   557         _handle = _v.divide(3),
   586         _handle = _v.divide(3),
   558         _color = this.model.get("color") || this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color");
   587         _color = this.model.get("color") || this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color");
   559     this.paper_coords = _p0b.add(_p1b).divide(2);
   588     this.paper_coords = _p0b.add(_p1b).divide(2);
   560     this.line.strokeColor = _color;
   589     this.line.strokeColor = _color;
   561     this.line.segments[0].point = _p0a;
   590     this.line.segments[0].point = _p0a;
   562     this.line.segments[1].point = this.paper_coords;
   591     this.line.segments[1].point = this.paper_coords;
   563     this.line.segments[1].handleIn = _handle.multiply(-1);
   592     this.line.segments[1].handleIn = _handle.multiply(-1);
   575         _a += 180;
   604         _a += 180;
   576         _textdelta = _textdelta.multiply(-1);
   605         _textdelta = _textdelta.multiply(-1);
   577     }
   606     }
   578     this.text.rotate(_a - this.text_angle);
   607     this.text.rotate(_a - this.text_angle);
   579     var _text = this.model.get("title");
   608     var _text = this.model.get("title");
   580     this.text.content = Rkns.Renderer.Utils.shortenText(_text, this.renderer.renkan.options.edge_label_max_length);
   609     this.text.content = Rkns.Renderer.Utils.shortenText(_text, this.options.edge_label_max_length);
   581     this.text.position = this.paper_coords.add(_textdelta);
   610     this.text.position = this.paper_coords.add(_textdelta);
   582     this.text_angle = _a;
   611     this.text_angle = _a;
   583     if (this.renderer.renkan.options.editor_mode) {
   612     if (this.options.editor_mode) {
   584 	    this.edit_button.moveTo(this.paper_coords);
   613 	    this.edit_button.moveTo(this.paper_coords);
   585 	    this.remove_button.moveTo(this.paper_coords);
   614 	    this.remove_button.moveTo(this.paper_coords);
   586     }
   615     }
   587     
   616     
   588     if (this.renderer.minimap) {
   617     if (this.renderer.minimap) {
   593 }
   622 }
   594 
   623 
   595 Rkns.Renderer.Edge.prototype.openEditor = function() {
   624 Rkns.Renderer.Edge.prototype.openEditor = function() {
   596     this.renderer.removeRepresentationsOfType("editor");
   625     this.renderer.removeRepresentationsOfType("editor");
   597     var _editor = this.renderer.addRepresentation("EdgeEditor",null);
   626     var _editor = this.renderer.addRepresentation("EdgeEditor",null);
   598     _editor.edge_representation = this;
   627     _editor.source_representation = this;
   599     _editor.draw();
   628     _editor.draw();
   600 }
   629 }
   601 
   630 
   602 Rkns.Renderer.Edge.prototype.select = function() {
   631 Rkns.Renderer.Edge.prototype.select = function() {
   603     this.line.strokeWidth = this.renderer.renkan.options.selected_edge_stroke_width;
   632     this.line.strokeWidth = this.options.selected_edge_stroke_width;
   604     if (this.renderer.isEditable()) {
   633     if (this.renderer.isEditable()) {
   605 	    this.edit_button.show();
   634 	    this.edit_button.show();
   606 	    this.remove_button.show();
   635 	    this.remove_button.show();
   607    	}
   636    	}
   608     if (!this.renderer.renkan.options.editor_mode) {
   637     if (!this.options.editor_mode) {
   609         this.openEditor();
   638         this.openEditor();
   610     }
   639     }
   611 }
   640 }
   612 
   641 
   613 Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
   642 Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
   614     if (!_newTarget || _newTarget.edge_representation !== this) {
   643     if (!_newTarget || _newTarget.source_representation !== this) {
   615     	if (this.renderer.renkan.options.editor_mode) {
   644     	if (this.options.editor_mode) {
   616 	        this.edit_button.hide();
   645 	        this.edit_button.hide();
   617 	        this.remove_button.hide();
   646 	        this.remove_button.hide();
   618         }
   647         }
   619         this.line.strokeWidth = this.renderer.renkan.options.edge_stroke_width;
   648         this.line.strokeWidth = this.options.edge_stroke_width;
   620     }
   649     }
   621 }
   650 }
   622 
   651 
   623 Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
   652 Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
   624     if (!this.renderer.renkan.read_only) {
   653     if (!this.renkan.read_only) {
   625         if (this.renderer.is_dragging) {
   654         if (this.renderer.is_dragging) {
   626             this.from_representation.saveCoords();
   655             this.from_representation.saveCoords();
   627             this.to_representation.saveCoords();
   656             this.to_representation.saveCoords();
   628         } else {
   657         } else {
   629             this.openEditor();
   658             this.openEditor();
   632     this.renderer.click_target = null;
   661     this.renderer.click_target = null;
   633     this.renderer.is_dragging = false;
   662     this.renderer.is_dragging = false;
   634 }
   663 }
   635 
   664 
   636 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   665 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   637 	if (this.renderer.renkan.options.editor_mode) {
   666 	if (this.options.editor_mode) {
   638 		if (!this.renderer.renkan.options.read_only) {
   667 		if (!this.options.read_only) {
   639 		    this.from_representation.paperShift(_delta);
   668 		    this.from_representation.paperShift(_delta);
   640 		    this.to_representation.paperShift(_delta);
   669 		    this.to_representation.paperShift(_delta);
   641 	    }
   670 	    }
   642 	} else {
   671 	} else {
   643 		this.renderer.paperShift(_delta);
   672 		this.renderer.paperShift(_delta);
   650     this.arrow.remove();
   679     this.arrow.remove();
   651     this.text.remove();
   680     this.text.remove();
   652     if (this.renderer.minimap) {
   681     if (this.renderer.minimap) {
   653    	    this.minimap_line.remove();
   682    	    this.minimap_line.remove();
   654     }
   683     }
   655     if (this.renderer.renkan.options.editor_mode) {
   684     if (this.options.editor_mode) {
   656 	    this.edit_button.destroy();
   685 	    this.edit_button.destroy();
   657 	    this.remove_button.destroy();
   686 	    this.remove_button.destroy();
   658    	}
   687    	}
   659     var _this = this;
   688     var _this = this;
   660     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   689     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   668 
   697 
   669 Rkns.Renderer.TempEdge.prototype._init = function() {
   698 Rkns.Renderer.TempEdge.prototype._init = function() {
   670     this.renderer.edge_layer.activate();
   699     this.renderer.edge_layer.activate();
   671     this.type = "temp-edge";
   700     this.type = "temp-edge";
   672     
   701     
   673     var _color = (this.project.get("users").get(this.renderer.renkan.current_user) || Rkns.Renderer._USER_PLACEHOLDER).get("color");
   702     var _color = (this.project.get("users").get(this.renkan.current_user) || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color");
   674     this.line = new paper.Path();
   703     this.line = new paper.Path();
   675     this.line.strokeColor = _color;
   704     this.line.strokeColor = _color;
   676     this.line.add([0,0],[0,0]);
   705     this.line.add([0,0],[0,0]);
   677     this.line.__representation = this;
   706     this.line.__representation = this;
   678     this.arrow = new paper.Path();
   707     this.arrow = new paper.Path();
   679     this.arrow.fillColor = _color;
   708     this.arrow.fillColor = _color;
   680     this.arrow.add(
   709     this.arrow.add(
   681     	[ 0, 0 ],
   710     	[ 0, 0 ],
   682     	[ this.renderer.renkan.options.edge_arrow_length, this.renderer.renkan.options.edge_arrow_width / 2 ],
   711     	[ this.options.edge_arrow_length, this.options.edge_arrow_width / 2 ],
   683     	[ 0, this.renderer.renkan.options.edge_arrow_width ]
   712     	[ 0, this.options.edge_arrow_width ]
   684 	);
   713 	);
   685     this.arrow.__representation = this;
   714     this.arrow.__representation = this;
   686     this.arrow_angle = 0;
   715     this.arrow_angle = 0;
   687 }
   716 }
   688 
   717 
   717     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
   746     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
   718         var _target = _hitResult.item.__representation;
   747         var _target = _hitResult.item.__representation;
   719         if (_target.type === "Node" && _model !== _target.model) {
   748         if (_target.type === "Node" && _model !== _target.model) {
   720             var _data = {
   749             var _data = {
   721                 id: Rkns.Utils.getUID('edge'),
   750                 id: Rkns.Utils.getUID('edge'),
   722                 created_by: this.renderer.renkan.current_user,
   751                 created_by: this.renkan.current_user,
   723                 from: _model.get("_id"),
   752                 from: _model.get("_id"),
   724                 to: _target.model.get("_id")
   753                 to: _target.model.get("_id")
   725             };
   754             };
   726             if (this.renderer.isEditable()) {
   755             if (this.renderer.isEditable()) {
   727             	this.project.addEdge(_data);
   756             	this.project.addEdge(_data);
   728             }
   757             }
   729         }
   758         }
   730         if (_model === _target.model || (_target.node_representation && _target.node_representation.model === _model)) {
   759         if (_model === _target.model || (_target.source_representation && _target.source_representation.model === _model)) {
   731             _endDrag = false;
   760             _endDrag = false;
   732             this.renderer.is_dragging = true;
   761             this.renderer.is_dragging = true;
   733         }
   762         }
   734     }
   763     }
   735     if (_endDrag) {
   764     if (_endDrag) {
   753     this.renderer.buttons_layer.activate();
   782     this.renderer.buttons_layer.activate();
   754     this.type = "editor";
   783     this.type = "editor";
   755     this.editor_block = new paper.Path();
   784     this.editor_block = new paper.Path();
   756     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   785     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   757     this.editor_block.add.apply(this.editor_block, _pts);
   786     this.editor_block.add.apply(this.editor_block, _pts);
   758     this.editor_block.strokeWidth = 2;
   787     this.editor_block.strokeWidth = this.options.tooltip_border_width;
   759     this.editor_block.strokeColor = "#999999";
   788     this.editor_block.strokeColor = this.options.tooltip_border_color;
   760     this.editor_block.fillColor = "#e0e0e0";
       
   761     this.editor_block.opacity = .8;
   789     this.editor_block.opacity = .8;
   762     this.editor_$ = Rkns.$('<div>')
   790     this.editor_$ = Rkns.$('<div>')
   763         .appendTo(this.renderer.editor_$)
   791         .appendTo(this.renderer.editor_$)
   764         .css({
   792         .css({
   765             position: "absolute",
   793             position: "absolute",
   777     + '<div class="Rk-Editor-p"><span class="Rk-Editor-Label"><%-translate("Node color:")%></span><div class="Rk-Edit-ColorPicker-Wrapper"><span class="Rk-Edit-Color" style="background:<%-node.color%>;"><span class="Rk-Edit-ColorTip"></span></span><ul class="Rk-Edit-ColorPicker">'
   805     + '<div class="Rk-Editor-p"><span class="Rk-Editor-Label"><%-translate("Node color:")%></span><div class="Rk-Edit-ColorPicker-Wrapper"><span class="Rk-Edit-Color" style="background:<%-node.color%>;"><span class="Rk-Edit-ColorTip"></span></span><ul class="Rk-Edit-ColorPicker">'
   778     + '<% _(Rkns.pickerColors).each(function(c) { %><li data-color="<%=c%>" style="background: <%=c%>"></li><% }); %></ul><span class="Rk-Edit-ColorPicker-Text"><%- translate("Choose color") %></span></div></div>'
   806     + '<% _(Rkns.pickerColors).each(function(c) { %><li data-color="<%=c%>" style="background: <%=c%>"></li><% }); %></ul><span class="Rk-Edit-ColorPicker-Text"><%- translate("Choose color") %></span></div></div>'
   779     + '<img class="Rk-Edit-ImgPreview" src="<%-node.image || node.image_placeholder%>" />'
   807     + '<img class="Rk-Edit-ImgPreview" src="<%-node.image || node.image_placeholder%>" />'
   780     + '<p><label><%-translate("Image URL:")%></label><input class="Rk-Edit-Image" type="text" value="<%-node.image%>"/></p>'
   808     + '<p><label><%-translate("Image URL:")%></label><input class="Rk-Edit-Image" type="text" value="<%-node.image%>"/></p>'
   781     + '<p><label><%-translate("Choose Image File:")%></label><input class="Rk-Edit-Image-File" type="file" accept="image/*"/></p>'    
   809     + '<p><label><%-translate("Choose Image File:")%></label><input class="Rk-Edit-Image-File" type="file" accept="image/*"/></p>'    
   782     + '<p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span> <span class="Rk-UserColor" style="background:<%-node.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(node.created_by_title, 25) %></p>'
   810     + '<% if (node.has_creator) { %><p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span> <span class="Rk-UserColor" style="background:<%-node.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(node.created_by_title, 25) %></p><% } %>'
   783 );
   811 );
   784 
   812 
   785 Rkns.Renderer.NodeEditor.prototype.readOnlyTemplate = Rkns._.template(
   813 Rkns.Renderer.NodeEditor.prototype.readOnlyTemplate = Rkns._.template(
   786     '<h2><span class="Rk-CloseX">&times;</span><span class="Rk-UserColor" style="background:<%-node.color%>;"></span>'
   814     '<h2><span class="Rk-CloseX">&times;</span><span class="Rk-UserColor" style="background:<%-node.color%>;"></span>'
   787     + '<span class="Rk-Display-Title"><% if (node.uri) { %><a href="<%-node.uri%>" target="_blank"><% } %><%-node.title%><% if (node.uri) { %></a><% } %></span></h2>'
   815     + '<span class="Rk-Display-Title"><% if (node.uri) { %><a href="<%-node.uri%>" target="_blank"><% } %><%-node.title%><% if (node.uri) { %></a><% } %></span></h2>'
   788     + '<% if (node.uri) { %><p class="Rk-Display-URI"><a href="<%-node.uri%>" target="_blank"><%-node.short_uri%></a></p><% } %>'
   816     + '<% if (node.uri) { %><p class="Rk-Display-URI"><a href="<%-node.uri%>" target="_blank"><%-node.short_uri%></a></p><% } %>'
   789     + '<p><%-node.description%></p>'
   817     + '<p><%-node.description%></p>'
   790     + '<p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span><span class="Rk-UserColor" style="background:<%-node.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(node.created_by_title, 25) %></p>'
   818     + '<% if (node.has_creator) { %><p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span><span class="Rk-UserColor" style="background:<%-node.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(node.created_by_title, 25) %></p><% } %>'
   791 );
   819 );
   792 
   820 
   793 Rkns.Renderer.NodeEditor.prototype.draw = function() {
   821 Rkns.Renderer.NodeEditor.prototype.draw = function() {
   794     var _model = this.node_representation.model,
   822     var _model = this.source_representation.model,
   795         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER,
   823         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan),
   796         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate ),
   824         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate ),
   797         _image_placeholder = this.renderer.renkan.options.static_url + "img/image-placeholder.png",
   825         _image_placeholder = this.options.static_url + "img/image-placeholder.png",
   798         _size = (_model.get("size") || 0);
   826         _size = (_model.get("size") || 0);
   799     this.editor_$
   827     this.editor_$
   800         .html(_template({
   828         .html(_template({
   801             node: {
   829             node: {
       
   830             	has_creator: !!_model.get("created_by"),
   802                 title: _model.get("title"),
   831                 title: _model.get("title"),
   803                 uri: _model.get("uri"),
   832                 uri: _model.get("uri"),
   804                 short_uri:  Rkns.Renderer.Utils.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
   833                 short_uri:  Rkns.Renderer.Utils.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
   805                 description: _model.get("description"),
   834                 description: _model.get("description"),
   806                 image: _model.get("image") || "",
   835                 image: _model.get("image") || "",
   808                 color: _model.get("color") || _created_by.get("color"),
   837                 color: _model.get("color") || _created_by.get("color"),
   809                 created_by_color: _created_by.get("color"),
   838                 created_by_color: _created_by.get("color"),
   810                 created_by_title: _created_by.get("title"),
   839                 created_by_title: _created_by.get("title"),
   811                 size: (_size > 0 ? "+" : "") + _size
   840                 size: (_size > 0 ? "+" : "") + _size
   812             },
   841             },
   813             translate: this.renderer.renkan.translate
   842             translate: this.renkan.translate
   814         }));
   843         }));
   815     this.redraw();
   844     this.redraw();
   816     var _this = this,
   845     var _this = this,
   817     	closeEditor = function() {
   846     	closeEditor = function() {
   818     		_this.renderer.removeRepresentation(_this);
   847     		_this.renderer.removeRepresentation(_this);
   850         this.editor_$.find(".Rk-Edit-Image-File").bind("change", function() {
   879         this.editor_$.find(".Rk-Edit-Image-File").bind("change", function() {
   851         	if (this.files.length) {
   880         	if (this.files.length) {
   852         		var f = this.files[0],
   881         		var f = this.files[0],
   853         			fr = new FileReader();
   882         			fr = new FileReader();
   854     			if (f.type.substr(0,5) !== "image") {
   883     			if (f.type.substr(0,5) !== "image") {
   855     				alert(_this.renderer.renkan.translate("This file is not an image"));
   884     				alert(_this.renkan.translate("This file is not an image"));
   856     				return;
   885     				return;
   857     			}
   886     			}
   858     			if (f.size > (Rkns.Renderer._IMAGE_MAX_KB * 1024)) {
   887     			if (f.size > (Rkns.Renderer._IMAGE_MAX_KB * 1024)) {
   859     				alert(_this.renderer.renkan.translate("Image size must be under ")+Rkns.Renderer._IMAGE_MAX_KB+_this.renderer.renkan.translate("KB"));
   888     				alert(_this.renkan.translate("Image size must be under ")+Rkns.Renderer._IMAGE_MAX_KB+_this.renkan.translate("KB"));
   860     				return;
   889     				return;
   861     			}
   890     			}
   862         		fr.onload = function(e) {
   891         		fr.onload = function(e) {
   863         			_this.editor_$.find(".Rk-Edit-Image").val(e.target.result);
   892         			_this.editor_$.find(".Rk-Edit-Image").val(e.target.result);
   864         			onFieldChange();
   893         			onFieldChange();
   871             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").show(); },
   900             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").show(); },
   872             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").hide(); }
   901             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").hide(); }
   873         );
   902         );
   874         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
   903         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
   875             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
   904             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
   876             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color")) }
   905             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color")) }
   877         ).click(function() {
   906         ).click(function() {
   878             if (_this.renderer.isEditable()) {
   907             if (_this.renderer.isEditable()) {
   879 	            _model.set("color", $(this).attr("data-color"));
   908 	            _model.set("color", $(this).attr("data-color"));
   880 				paper.view.draw();
   909 				paper.view.draw();
   881             } else {
   910             } else {
   907         _this.redraw();
   936         _this.redraw();
   908     });
   937     });
   909 }
   938 }
   910 
   939 
   911 Rkns.Renderer.NodeEditor.prototype.redraw = function() {
   940 Rkns.Renderer.NodeEditor.prototype.redraw = function() {
   912     var _coords = this.node_representation.paper_coords;
   941     var _coords = this.source_representation.paper_coords;
   913     Rkns.Renderer.Utils.drawEditBox(this.renderer.renkan.options, _coords, this.editor_block, this.node_representation.circle_radius * .75, this.editor_$);
   942     Rkns.Renderer.Utils.drawEditBox(this.options, _coords, this.editor_block, this.source_representation.circle_radius * .75, this.editor_$);
   914     this.editor_$.show();
   943     this.editor_$.show();
   915     paper.view.draw();
   944     paper.view.draw();
   916 }
   945 }
   917 
   946 
   918 Rkns.Renderer.NodeEditor.prototype.destroy = function() {
   947 Rkns.Renderer.NodeEditor.prototype.destroy = function() {
   928     this.renderer.buttons_layer.activate();
   957     this.renderer.buttons_layer.activate();
   929     this.type = "editor";
   958     this.type = "editor";
   930     this.editor_block = new paper.Path();
   959     this.editor_block = new paper.Path();
   931     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   960     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   932     this.editor_block.add.apply(this.editor_block, _pts);
   961     this.editor_block.add.apply(this.editor_block, _pts);
   933     this.editor_block.strokeWidth = 2;
   962     this.editor_block.strokeWidth = this.options.tooltip_border_width;
   934     this.editor_block.strokeColor = "#999999";
   963     this.editor_block.strokeColor = this.options.tooltip_border_color;
   935     this.editor_block.fillColor = "#e0e0e0";
       
   936     this.editor_block.opacity = .8;
   964     this.editor_block.opacity = .8;
   937     this.editor_$ = Rkns.$('<div>')
   965     this.editor_$ = Rkns.$('<div>')
   938         .appendTo(this.renderer.editor_$)
   966         .appendTo(this.renderer.editor_$)
   939         .css({
   967         .css({
   940             position: "absolute",
   968             position: "absolute",
   955     + '<div class="Rk-Editor-p"><span class="Rk-Editor-Label"><%-translate("Edge color:")%></span><div class="Rk-Edit-ColorPicker-Wrapper"><span class="Rk-Edit-Color" style="background:<%-edge.color%>;"><span class="Rk-Edit-ColorTip"></span></span><ul class="Rk-Edit-ColorPicker">'
   983     + '<div class="Rk-Editor-p"><span class="Rk-Editor-Label"><%-translate("Edge color:")%></span><div class="Rk-Edit-ColorPicker-Wrapper"><span class="Rk-Edit-Color" style="background:<%-edge.color%>;"><span class="Rk-Edit-ColorTip"></span></span><ul class="Rk-Edit-ColorPicker">'
   956     + '<% _(Rkns.pickerColors).each(function(c) { %><li data-color="<%=c%>" style="background: <%=c%>"></li><% }); %></ul><span class="Rk-Edit-ColorPicker-Text"><%- translate("Choose color") %></span></div></div>'
   984     + '<% _(Rkns.pickerColors).each(function(c) { %><li data-color="<%=c%>" style="background: <%=c%>"></li><% }); %></ul><span class="Rk-Edit-ColorPicker-Text"><%- translate("Choose color") %></span></div></div>'
   957     + '<p><span class="Rk-Edit-Direction"><%- translate("Change edge direction") %></span></p>'
   985     + '<p><span class="Rk-Edit-Direction"><%- translate("Change edge direction") %></span></p>'
   958     + '<p><span class="Rk-Editor-Label"><%-translate("From:")%></span><span class="Rk-UserColor" style="background:<%-edge.from_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.from_title, 25) %></p>'
   986     + '<p><span class="Rk-Editor-Label"><%-translate("From:")%></span><span class="Rk-UserColor" style="background:<%-edge.from_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.from_title, 25) %></p>'
   959     + '<p><span class="Rk-Editor-Label"><%-translate("To:")%></span><span class="Rk-UserColor" style="background:<%-edge.to_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.to_title, 25) %></p>'
   987     + '<p><span class="Rk-Editor-Label"><%-translate("To:")%></span><span class="Rk-UserColor" style="background:<%-edge.to_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.to_title, 25) %></p>'
   960     + '<p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span><span class="Rk-UserColor" style="background:<%-edge.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.created_by_title, 25) %></p>'
   988     + '<% if (edge.has_creator) { %><p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span><span class="Rk-UserColor" style="background:<%-edge.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.created_by_title, 25) %></p><% } %>'
   961 );
   989 );
   962 
   990 
   963 Rkns.Renderer.EdgeEditor.prototype.readOnlyTemplate = Rkns._.template(
   991 Rkns.Renderer.EdgeEditor.prototype.readOnlyTemplate = Rkns._.template(
   964     '<h2><span class="Rk-CloseX">&times;</span><span class="Rk-UserColor" style="background:<%-edge.color%>;"></span>'
   992     '<h2><span class="Rk-CloseX">&times;</span><span class="Rk-UserColor" style="background:<%-edge.color%>;"></span>'
   965     + '<span class="Rk-Display-Title"><% if (edge.uri) { %><a href="<%-edge.uri%>" target="_blank"><% } %><%-edge.title%><% if (edge.uri) { %></a><% } %></span></h2>'
   993     + '<span class="Rk-Display-Title"><% if (edge.uri) { %><a href="<%-edge.uri%>" target="_blank"><% } %><%-edge.title%><% if (edge.uri) { %></a><% } %></span></h2>'
   966     + '<% if (edge.uri) { %><p class="Rk-Display-URI"><a href="<%-edge.uri%>" target="_blank"><%-edge.short_uri%></a></p><% } %>'
   994     + '<% if (edge.uri) { %><p class="Rk-Display-URI"><a href="<%-edge.uri%>" target="_blank"><%-edge.short_uri%></a></p><% } %>'
   967     + '<p><%-edge.description%></p>'
   995     + '<p><%-edge.description%></p>'
   968     + '<p><span class="Rk-Editor-Label"><%-translate("From:")%></span><span class="Rk-UserColor" style="background:<%-edge.from_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.from_title, 25) %></p>'
   996     + '<p><span class="Rk-Editor-Label"><%-translate("From:")%></span><span class="Rk-UserColor" style="background:<%-edge.from_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.from_title, 25) %></p>'
   969     + '<p><span class="Rk-Editor-Label"><%-translate("To:")%></span><span class="Rk-UserColor" style="background:<%-edge.to_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.to_title, 25) %></p>'
   997     + '<p><span class="Rk-Editor-Label"><%-translate("To:")%></span><span class="Rk-UserColor" style="background:<%-edge.to_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.to_title, 25) %></p>'
   970     + '<p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span><span class="Rk-UserColor" style="background:<%-edge.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.created_by_title, 25) %></p>'
   998     + '<% if (edge.has_creator) { %><p><span class="Rk-Editor-Label"><%-translate("Created by:")%></span><span class="Rk-UserColor" style="background:<%-edge.created_by_color%>;"></span><%- Rkns.Renderer.Utils.shortenText(edge.created_by_title, 25) %></p><% } %>'
   971 );
   999 );
   972 
  1000 
   973 Rkns.Renderer.EdgeEditor.prototype.draw = function() {
  1001 Rkns.Renderer.EdgeEditor.prototype.draw = function() {
   974     var _model = this.edge_representation.model,
  1002     var _model = this.source_representation.model,
   975         _from_model = _model.get("from"),
  1003         _from_model = _model.get("from"),
   976         _to_model = _model.get("to"),
  1004         _to_model = _model.get("to"),
   977         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER,
  1005         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan),
   978         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate);
  1006         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate);
   979     this.editor_$
  1007     this.editor_$
   980         .html(_template({
  1008         .html(_template({
   981             edge: {
  1009             edge: {
       
  1010             	has_creator: !!_model.get("created_by"),
   982                 title: _model.get("title"),
  1011                 title: _model.get("title"),
   983                 uri: _model.get("uri"),
  1012                 uri: _model.get("uri"),
   984                 short_uri:  Rkns.Renderer.Utils.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
  1013                 short_uri:  Rkns.Renderer.Utils.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40),
   985                 description: _model.get("description"),
  1014                 description: _model.get("description"),
   986                 color: _model.get("color") || _created_by.get("color"),
  1015                 color: _model.get("color") || _created_by.get("color"),
   987                 from_title: _from_model.get("title"),
  1016                 from_title: _from_model.get("title"),
   988                 to_title: _to_model.get("title"),
  1017                 to_title: _to_model.get("title"),
   989                 from_color: _from_model.get("color") || (_from_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color"),
  1018                 from_color: _from_model.get("color") || (_from_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color"),
   990                 to_color: _to_model.get("color") || (_to_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color"),
  1019                 to_color: _to_model.get("color") || (_to_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color"),
   991                 created_by_color: _created_by.get("color"),
  1020                 created_by_color: _created_by.get("color"),
   992                 created_by_title: _created_by.get("title")
  1021                 created_by_title: _created_by.get("title")
   993             },
  1022             },
   994             translate: this.renderer.renkan.translate,
  1023             translate: this.renkan.translate,
   995             properties: this.renderer.renkan.options.properties
  1024             properties: this.options.properties
   996         }));
  1025         }));
   997     this.redraw();
  1026     this.redraw();
   998     var _this = this,
  1027     var _this = this,
   999     	closeEditor = function() {
  1028     	closeEditor = function() {
  1000 	        _this.renderer.removeRepresentation(_this);
  1029 	        _this.renderer.removeRepresentation(_this);
  1045             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").show(); },
  1074             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").show(); },
  1046             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").hide(); }
  1075             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").hide(); }
  1047         );
  1076         );
  1048         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
  1077         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
  1049             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
  1078             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
  1050             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color")); }
  1079             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color")); }
  1051         ).click(function() {
  1080         ).click(function() {
  1052 			if (_this.renderer.isEditable()) {
  1081 			if (_this.renderer.isEditable()) {
  1053             	_model.set("color", $(this).attr("data-color"));
  1082             	_model.set("color", $(this).attr("data-color"));
  1054             	paper.view.draw();
  1083             	paper.view.draw();
  1055             } else {
  1084             } else {
  1058         });
  1087         });
  1059     }
  1088     }
  1060 }
  1089 }
  1061 
  1090 
  1062 Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
  1091 Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
  1063     var _coords = this.edge_representation.paper_coords;
  1092     var _coords = this.source_representation.paper_coords;
  1064     Rkns.Renderer.Utils.drawEditBox(this.renderer.renkan.options, _coords, this.editor_block, 5, this.editor_$);
  1093     Rkns.Renderer.Utils.drawEditBox(this.options, _coords, this.editor_block, 5, this.editor_$);
  1065     this.editor_$.show();
  1094     this.editor_$.show();
  1066     paper.view.draw();
  1095     paper.view.draw();
  1067 }
  1096 }
  1068 
  1097 
  1069 Rkns.Renderer.EdgeEditor.prototype.destroy = function() {
  1098 Rkns.Renderer.EdgeEditor.prototype.destroy = function() {
  1071     this.editor_$.detach();
  1100     this.editor_$.detach();
  1072 }
  1101 }
  1073 
  1102 
  1074 /* */
  1103 /* */
  1075 
  1104 
  1076 Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1105 Rkns.Renderer._NodeButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton);
  1077 
  1106 
  1078 Rkns.Renderer.NodeEditButton.prototype._init = function() {
  1107 Rkns.Renderer._NodeButton.prototype.setSectorSize = function() {
  1079     this.type = "Node-edit-button";
  1108 	var sectorInner = this.source_representation.circle_radius;
  1080     this.lastSectorInner = 0;
       
  1081 }
       
  1082 
       
  1083 Rkns.Renderer.NodeEditButton.prototype.setSectorSize = function() {
       
  1084 	var sectorInner = this.node_representation.circle_radius;
       
  1085 	if (sectorInner !== this.lastSectorInner) {
  1109 	if (sectorInner !== this.lastSectorInner) {
  1086 		if (this.sector) {
  1110 		if (this.sector) {
  1087 			this.sector.destroy();
  1111 			this.sector.destroy();
  1088 		}
  1112 		}
  1089 		this.sector = Rkns.Renderer.Utils.sector(this, 1 + sectorInner, Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner, - 90, 30, 1, this.renderer.renkan.options.static_url+'img/edit.png', this.renderer.renkan.translate("Edit"));
  1113 		this.sector = Rkns.Renderer.Utils.sector(
       
  1114 			this, 1 + sectorInner,
       
  1115 			Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner,
       
  1116 			this.startAngle,
       
  1117 			this.endAngle,
       
  1118 			1,
       
  1119 			this.options.static_url + this.imageFile,
       
  1120 			this.renkan.translate(this.text)
       
  1121 		);
  1090 		this.lastSectorInner = sectorInner;
  1122 		this.lastSectorInner = sectorInner;
  1091 	}
  1123 	}
  1092 }
  1124 }
  1093 
  1125 
  1094 Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
  1126 /* */
  1095     this.sector.moveTo(_pos);
  1127 
  1096 }
  1128 Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
  1097 
  1129 
  1098 Rkns.Renderer.NodeEditButton.prototype.show = function() {
  1130 Rkns.Renderer.NodeEditButton.prototype._init = function() {
  1099     this.sector.show();
  1131     this.type = "Node-edit-button";
  1100 }
  1132     this.lastSectorInner = 0;
  1101 
  1133     this.startAngle = -225;
  1102 Rkns.Renderer.NodeEditButton.prototype.hide = function() {
  1134     this.endAngle = -135;
  1103     this.sector.hide();
  1135     this.imageFile = 'img/edit.png';
  1104 }
  1136     this.text = "Edit";
  1105 
       
  1106 Rkns.Renderer.NodeEditButton.prototype.select = function() {
       
  1107     this.sector.select();
       
  1108 }
       
  1109 
       
  1110 Rkns.Renderer.NodeEditButton.prototype.unselect = function(_newTarget) {
       
  1111     this.sector.unselect();
       
  1112     if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) {
       
  1113         this.node_representation.unselect();
       
  1114     }
       
  1115 }
  1137 }
  1116 
  1138 
  1117 Rkns.Renderer.NodeEditButton.prototype.mouseup = function() {
  1139 Rkns.Renderer.NodeEditButton.prototype.mouseup = function() {
  1118     if (!this.renderer.is_dragging) {
  1140     if (!this.renderer.is_dragging) {
  1119         this.node_representation.openEditor();
  1141         this.source_representation.openEditor();
  1120     }
  1142     }
  1121 }
       
  1122 
       
  1123 Rkns.Renderer.NodeEditButton.prototype.destroy = function() {
       
  1124     this.sector.destroy();
       
  1125 }
  1143 }
  1126 
  1144 
  1127 /* */
  1145 /* */
  1128 
  1146 
  1129 Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1147 Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
  1130 
  1148 
  1131 Rkns.Renderer.NodeRemoveButton.prototype._init = function() {
  1149 Rkns.Renderer.NodeRemoveButton.prototype._init = function() {
  1132     this.type = "Node-remove-button";
  1150     this.type = "Node-remove-button";
  1133     this.lastSectorInner = 0;
  1151     this.lastSectorInner = 0;
  1134 }
  1152     this.startAngle = -45;
  1135 
  1153     this.endAngle = 45;
  1136 Rkns.Renderer.NodeRemoveButton.prototype.setSectorSize = function() {
  1154     this.imageFile = 'img/remove.png';
  1137 	var sectorInner = this.node_representation.circle_radius;
  1155     this.text = "Remove";
  1138 	if (sectorInner !== this.lastSectorInner) {
       
  1139 		if (this.sector) {
       
  1140 			this.sector.destroy();
       
  1141 		}
       
  1142 		this.sector = Rkns.Renderer.Utils.sector(this, 1 + sectorInner, Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner, - 210, - 90, 1, this.renderer.renkan.options.static_url+'img/remove.png', this.renderer.renkan.translate("Remove"));
       
  1143 		this.lastSectorInner = sectorInner;
       
  1144 	}
       
  1145 }
       
  1146 
       
  1147 Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
       
  1148     this.sector.moveTo(_pos);
       
  1149 }
       
  1150 
       
  1151 Rkns.Renderer.NodeRemoveButton.prototype.show = function() {
       
  1152     this.sector.show();
       
  1153 }
       
  1154 
       
  1155 Rkns.Renderer.NodeRemoveButton.prototype.hide = function() {
       
  1156     this.sector.hide();
       
  1157 }
       
  1158 
       
  1159 Rkns.Renderer.NodeRemoveButton.prototype.select = function() {
       
  1160     this.sector.select();
       
  1161 }
       
  1162 
       
  1163 Rkns.Renderer.NodeRemoveButton.prototype.unselect = function(_newTarget) {
       
  1164     this.sector.unselect();
       
  1165     if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) {
       
  1166         this.node_representation.unselect();
       
  1167     }
       
  1168 }
  1156 }
  1169 
  1157 
  1170 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
  1158 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
  1171     this.renderer.removeRepresentationsOfType("editor");
  1159     this.renderer.removeRepresentationsOfType("editor");
  1172     if (this.renderer.isEditable() && confirm(this.renderer.renkan.translate('Do you really wish to remove node ') + '"' + this.node_representation.model.get("title") + '"?')) {
  1160     if (this.renderer.isEditable() && confirm(this.renkan.translate('Do you really wish to remove node ') + '"' + this.source_representation.model.get("title") + '"?')) {
  1173         this.project.removeNode(this.node_representation.model);
  1161         this.project.removeNode(this.source_representation.model);
  1174     }
  1162     }
  1175 }
       
  1176 
       
  1177 Rkns.Renderer.NodeRemoveButton.prototype.destroy = function() {
       
  1178     this.sector.destroy();
       
  1179 }
  1163 }
  1180 
  1164 
  1181 /* */
  1165 /* */
  1182 
  1166 
  1183 Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1167 Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
  1184 
  1168 
  1185 Rkns.Renderer.NodeLinkButton.prototype._init = function() {
  1169 Rkns.Renderer.NodeLinkButton.prototype._init = function() {
  1186     this.type = "Node-link-button";
  1170     this.type = "Node-link-button";
  1187     this.lastSectorInner = 0;
  1171     this.lastSectorInner = 0;
  1188 }
  1172     this.startAngle = -135;
  1189 
  1173     this.endAngle = -45;
  1190 Rkns.Renderer.NodeLinkButton.prototype.setSectorSize = function() {
  1174     this.imageFile = 'img/link.png';
  1191 	var sectorInner = this.node_representation.circle_radius;
  1175     this.text = "Link to another node";
  1192 	if (sectorInner !== this.lastSectorInner) {
       
  1193 		if (this.sector) {
       
  1194 			this.sector.destroy();
       
  1195 		}
       
  1196 		this.sector = Rkns.Renderer.Utils.sector(this, 1 + sectorInner, Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner, 30, 150, 1, this.renderer.renkan.options.static_url+'img/link.png', this.renderer.renkan.translate("Link to another node"));
       
  1197 		this.lastSectorInner = sectorInner;
       
  1198 	}
       
  1199 }
       
  1200 
       
  1201 Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
       
  1202     this.sector.moveTo(_pos);
       
  1203 }
       
  1204 
       
  1205 Rkns.Renderer.NodeLinkButton.prototype.show = function() {
       
  1206     this.sector.show();
       
  1207 }
       
  1208 
       
  1209 Rkns.Renderer.NodeLinkButton.prototype.hide = function() {
       
  1210     this.sector.hide();
       
  1211 }
       
  1212 
       
  1213 Rkns.Renderer.NodeLinkButton.prototype.select = function() {
       
  1214     this.sector.select();
       
  1215 }
       
  1216 
       
  1217 Rkns.Renderer.NodeLinkButton.prototype.unselect = function(_newTarget) {
       
  1218     this.sector.unselect();
       
  1219     if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) {
       
  1220         this.node_representation.unselect();
       
  1221     }
       
  1222 }
       
  1223 
       
  1224 Rkns.Renderer.NodeLinkButton.prototype.destroy = function() {
       
  1225     this.sector.destroy();
       
  1226 }
  1176 }
  1227 
  1177 
  1228 /* */
  1178 /* */
  1229 
  1179 
  1230 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1180 Rkns.Renderer.NodeEnlargeButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
       
  1181 
       
  1182 Rkns.Renderer.NodeEnlargeButton.prototype._init = function() {
       
  1183     this.type = "Node-enlarge-button";
       
  1184     this.lastSectorInner = 0;
       
  1185     this.startAngle = 45;
       
  1186     this.endAngle = 90;
       
  1187     this.imageFile = 'img/enlarge.png';
       
  1188     this.text = "Enlarge";
       
  1189 }
       
  1190 
       
  1191 Rkns.Renderer.NodeEnlargeButton.prototype.mouseup = function() {
       
  1192 	var _newsize = 1 + (this.source_representation.model.get("size") || 0);
       
  1193 	this.source_representation.model.set("size", _newsize);
       
  1194 	this.source_representation.select();
       
  1195 	this.select();
       
  1196 	paper.view.draw();
       
  1197 }
       
  1198 
       
  1199 /* */
       
  1200 
       
  1201 Rkns.Renderer.NodeShrinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton);
       
  1202 
       
  1203 Rkns.Renderer.NodeShrinkButton.prototype._init = function() {
       
  1204     this.type = "Node-shrink-button";
       
  1205     this.lastSectorInner = 0;
       
  1206     this.startAngle = 90;
       
  1207     this.endAngle = 135;
       
  1208     this.imageFile = 'img/shrink.png';
       
  1209     this.text = "Shrink";
       
  1210 }
       
  1211 
       
  1212 Rkns.Renderer.NodeShrinkButton.prototype.mouseup = function() {
       
  1213 	var _newsize = -1 + (this.source_representation.model.get("size") || 0);
       
  1214 	this.source_representation.model.set("size", _newsize);
       
  1215 	this.source_representation.select();
       
  1216 	this.select();
       
  1217 	paper.view.draw();
       
  1218 }
       
  1219 
       
  1220 /* */
       
  1221 
       
  1222 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton);
  1231 
  1223 
  1232 Rkns.Renderer.EdgeEditButton.prototype._init = function() {
  1224 Rkns.Renderer.EdgeEditButton.prototype._init = function() {
  1233     this.type = "Edge-edit-button";
  1225     this.type = "Edge-edit-button";
  1234     this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 90, 90, 1, this.renderer.renkan.options.static_url+'img/edit.png', this.renderer.renkan.translate("Edit"));
  1226     this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 90, 90, 1, this.options.static_url+'img/edit.png', this.renkan.translate("Edit"));
  1235 }
       
  1236 
       
  1237 Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) {
       
  1238     this.sector.moveTo(_pos);
       
  1239 }
       
  1240 
       
  1241 Rkns.Renderer.EdgeEditButton.prototype.show = function() {
       
  1242     this.sector.show();
       
  1243 }
       
  1244 
       
  1245 Rkns.Renderer.EdgeEditButton.prototype.hide = function() {
       
  1246     this.sector.hide();
       
  1247 }
       
  1248 
       
  1249 Rkns.Renderer.EdgeEditButton.prototype.select = function() {
       
  1250     this.sector.select();
       
  1251 }
       
  1252 
       
  1253 Rkns.Renderer.EdgeEditButton.prototype.unselect = function(_newTarget) {
       
  1254     this.sector.unselect();
       
  1255     if (!_newTarget || (_newTarget !== this.edge_representation && _newTarget.edge_representation !== this.edge_representation)) {
       
  1256         this.edge_representation.unselect();
       
  1257     }
       
  1258 }
  1227 }
  1259 
  1228 
  1260 Rkns.Renderer.EdgeEditButton.prototype.mouseup = function() {
  1229 Rkns.Renderer.EdgeEditButton.prototype.mouseup = function() {
  1261     if (!this.renderer.is_dragging) {
  1230     if (!this.renderer.is_dragging) {
  1262         this.edge_representation.openEditor();
  1231         this.source_representation.openEditor();
  1263     }
  1232     }
  1264 }
       
  1265 
       
  1266 Rkns.Renderer.EdgeEditButton.prototype.destroy = function() {
       
  1267     this.sector.destroy();
       
  1268 }
  1233 }
  1269 
  1234 
  1270 /* */
  1235 /* */
  1271 
  1236 
  1272 Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1237 Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton);
  1273 
  1238 
  1274 Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
  1239 Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
  1275     this.type = "Edge-remove-button";
  1240     this.type = "Edge-remove-button";
  1276     this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 270, -90, 1, this.renderer.renkan.options.static_url+'img/remove.png', this.renderer.renkan.translate("Remove"));
  1241     this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 270, -90, 1, this.options.static_url+'img/remove.png', this.renkan.translate("Remove"));
  1277 }
       
  1278 Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) {
       
  1279     this.sector.moveTo(_pos);
       
  1280 }
       
  1281 
       
  1282 Rkns.Renderer.EdgeRemoveButton.prototype.show = function() {
       
  1283     this.sector.show();
       
  1284 }
       
  1285 
       
  1286 Rkns.Renderer.EdgeRemoveButton.prototype.hide = function() {
       
  1287     this.sector.hide();
       
  1288 }
       
  1289 
       
  1290 Rkns.Renderer.EdgeRemoveButton.prototype.select = function() {
       
  1291     this.sector.select();
       
  1292 }
       
  1293 
       
  1294 Rkns.Renderer.EdgeRemoveButton.prototype.unselect = function(_newTarget) {
       
  1295     this.sector.unselect();
       
  1296     if (!_newTarget || (_newTarget !== this.edge_representation && _newTarget.edge_representation !== this.edge_representation)) {
       
  1297         this.edge_representation.unselect();
       
  1298     }
       
  1299 }
  1242 }
  1300 
  1243 
  1301 Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
  1244 Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
  1302     this.renderer.removeRepresentationsOfType("editor");
  1245     this.renderer.removeRepresentationsOfType("editor");
  1303     if (this.renderer.isEditable() && confirm(this.renderer.renkan.translate('Do you really wish to remove edge ') + '"' + this.edge_representation.model.get("title") + '"?')) {
  1246     if (this.renderer.isEditable() && confirm(this.renkan.translate('Do you really wish to remove edge ') + '"' + this.source_representation.model.get("title") + '"?')) {
  1304         this.project.removeEdge(this.edge_representation.model);
  1247         this.project.removeEdge(this.source_representation.model);
  1305     }
  1248     }
  1306 }
       
  1307 
       
  1308 Rkns.Renderer.EdgeRemoveButton.prototype.destroy = function() {
       
  1309     this.sector.destroy();
       
  1310 }
  1249 }
  1311 
  1250 
  1312 /* */
  1251 /* */
  1313 
  1252 
  1314 Rkns.Renderer.MiniFrame = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1253 Rkns.Renderer.MiniFrame = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1354 	    }
  1293 	    }
  1355 	    
  1294 	    
  1356 	    this.minimap.background_layer.activate();
  1295 	    this.minimap.background_layer.activate();
  1357 	    this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size);
  1296 	    this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size);
  1358 	    this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));
  1297 	    this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));
  1359 	    this.minimap.rectangle.fillColor = '#ffffff';
  1298 	    this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color;
  1360 	    this.minimap.rectangle.strokeColor = '#cccccc';
  1299 	    this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color;
  1361 	    this.minimap.rectangle.strokeWidth = 4;
  1300 	    this.minimap.rectangle.strokeWidth = 4;
  1362 	    this.minimap.offset = new paper.Point(this.minimap.size.divide(2));
  1301 	    this.minimap.offset = new paper.Point(this.minimap.size.divide(2));
  1363 	    this.minimap.scale = .1;
  1302 	    this.minimap.scale = .1;
  1364 	    
  1303 	    
  1365 	    this.minimap.node_layer.activate();
  1304 	    this.minimap.node_layer.activate();
  1700 	    }, 2000);
  1639 	    }, 2000);
  1701     }
  1640     }
  1702 }
  1641 }
  1703 
  1642 
  1704 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
  1643 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
  1705     '<div class="Rk-TopBar"><% if (!options.editor_mode) { %><h2 class="Rk-PadTitle"><%- project.get("title") || translate("Untitled project")%></h2>'
  1644     '<% if (options.show_top_bar) { %><div class="Rk-TopBar"><% if (!options.editor_mode) { %><h2 class="Rk-PadTitle"><%- project.get("title") || translate("Untitled project")%></h2>'
  1706     + '<% } else { %><input type="text" class="Rk-PadTitle" value="<%- project.get("title") || "" %>" placeholder="<%-translate("Untitled project")%>" /><% } %>'
  1645     + '<% } else { %><input type="text" class="Rk-PadTitle" value="<%- project.get("title") || "" %>" placeholder="<%-translate("Untitled project")%>" /><% } %>'
  1707     + '<div class="Rk-Users"><div class="Rk-CurrentUser"><span class="Rk-CurrentUser-Color"></span><span class="Rk-CurrentUser-Name">&lt;unknown user&gt;</span></div><ul class="Rk-UserList"></ul></div>'
  1646     + '<div class="Rk-Users"><div class="Rk-CurrentUser"><span class="Rk-CurrentUser-Color"></span><span class="Rk-CurrentUser-Name">&lt;unknown user&gt;</span></div><ul class="Rk-UserList"></ul></div>'
  1708     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-FullScreen-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Full Screen")%></div></div></div>'
  1647     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-FullScreen-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Full Screen")%></div></div></div>'
  1709     + '<% if (options.editor_mode) { %>'
  1648     + '<% if (options.editor_mode) { %>'
  1710     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddNode-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Node")%></div></div></div>'
  1649     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddNode-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Node")%></div></div></div>'
  1711     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddEdge-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Edge")%></div></div></div>'
  1650     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddEdge-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Edge")%></div></div></div>'
  1712     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Save-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"> </div></div></div>'
  1651     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Save-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"> </div></div></div>'
  1713     + '<div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents">'
  1652     + '<div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents">'
  1714     + '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a>'
  1653     + '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a>'
  1715     + '<div class="Rk-TopBar-Separator"></div></div>'
  1654     + '<div class="Rk-TopBar-Separator"></div></div>'
  1716     + '<% } %>'
  1655     + '<% } } %>'
  1717     + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
  1656     + '<div class="Rk-Editing-Space<% if (!options.show_top_bar) { %> Rk-Editing-Space-Full<% } %>"><canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
  1718     + '<% if (options.show_bins) { %><div class="Rk-Fold-Bins">&laquo;</div><% } %>'
  1657     + '<% if (options.show_bins) { %><div class="Rk-Fold-Bins">&laquo;</div><% } %>'
  1719     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div></div>'
  1658     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div></div>'
  1720     + '</div>'
  1659     + '</div></div>'
  1721 );
  1660 );
  1722 
  1661 
  1723 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
  1662 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
  1724     var _bundle = Rkns._(this.bundles).find(function(_bundle) {
  1663     var _bundle = Rkns._(this.bundles).find(function(_bundle) {
  1725         return ( 
  1664         return ( 
  1967         var _hitResult = paper.project.hitTest(_event.point);
  1906         var _hitResult = paper.project.hitTest(_event.point);
  1968         if (this.isEditable() && _hitResult && typeof _hitResult.item.__representation !== "undefined") {
  1907         if (this.isEditable() && _hitResult && typeof _hitResult.item.__representation !== "undefined") {
  1969             this.click_target = _hitResult.item.__representation;
  1908             this.click_target = _hitResult.item.__representation;
  1970             if (this.click_target.type === "Node-link-button") {
  1909             if (this.click_target.type === "Node-link-button") {
  1971                 this.removeRepresentationsOfType("editor");
  1910                 this.removeRepresentationsOfType("editor");
  1972                 this.addTempEdge(this.click_target.node_representation, _event.point);
  1911                 this.addTempEdge(this.click_target.source_representation, _event.point);
  1973             }
  1912             }
  1974         } else {
  1913         } else {
  1975             this.click_target = null;
  1914             this.click_target = null;
  1976             if (this.isEditable() && this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
  1915             if (this.isEditable() && this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
  1977                 var _coords = this.toModelCoords(_event.point),
  1916                 var _coords = this.toModelCoords(_event.point),