client/js/paper-renderer.js
changeset 114 110f99eb417e
parent 113 fac7354c55d2
child 116 07f9fc847d5d
equal deleted inserted replaced
113:fac7354c55d2 114:110f99eb417e
   205             this._changeBinding = function() {
   205             this._changeBinding = function() {
   206                 _this.redraw();
   206                 _this.redraw();
   207             }
   207             }
   208             this._removeBinding = function() {
   208             this._removeBinding = function() {
   209                 _renderer.removeRepresentation(_this);
   209                 _renderer.removeRepresentation(_this);
   210                 _renderer.redraw();
   210                 _(function() {
       
   211                 	_renderer.redraw()
       
   212             	}).defer();
   211             }
   213             }
   212             this.model.on("change", this._changeBinding );
   214             this.model.on("change", this._changeBinding );
   213             this.model.on("remove", this._removeBinding );
   215             this.model.on("remove", this._removeBinding );
   214         }
   216         }
   215     }
   217     }
   254     this.title = new paper.PointText([0,0]);
   256     this.title = new paper.PointText([0,0]);
   255     this.title.characterStyle = {
   257     this.title.characterStyle = {
   256         fontSize: Rkns.Renderer._NODE_FONT_SIZE,
   258         fontSize: Rkns.Renderer._NODE_FONT_SIZE,
   257         fillColor: 'black'
   259         fillColor: 'black'
   258     };
   260     };
   259     if (this.renderer.renkan.read_only) {
   261     if (this.renderer.renkan.options.editor_mode) {
   260         this.edit_button = new Rkns.Renderer._BaseRepresentation(this.renderer, null);
       
   261         this.remove_button = new Rkns.Renderer._BaseRepresentation(this.renderer, null);
       
   262         this.link_button = new Rkns.Renderer._BaseRepresentation(this.renderer, null);
       
   263     } else {
       
   264         this.edit_button = new Rkns.Renderer.NodeEditButton(this.renderer, null);
   262         this.edit_button = new Rkns.Renderer.NodeEditButton(this.renderer, null);
   265         this.edit_button.node_representation = this;
   263         this.edit_button.node_representation = this;
   266         this.remove_button = new Rkns.Renderer.NodeRemoveButton(this.renderer, null);
   264         this.remove_button = new Rkns.Renderer.NodeRemoveButton(this.renderer, null);
   267         this.remove_button.node_representation = this;
   265         this.remove_button.node_representation = this;
   268         this.link_button = new Rkns.Renderer.NodeLinkButton(this.renderer, null);
   266         this.link_button = new Rkns.Renderer.NodeLinkButton(this.renderer, null);
   282     if (!this.is_dragging || !this.paper_coords) {
   280     if (!this.is_dragging || !this.paper_coords) {
   283         this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   281         this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   284     }
   282     }
   285     this.circle_radius = _baseRadius * this.renderer.scale;
   283     this.circle_radius = _baseRadius * this.renderer.scale;
   286     if (this.last_circle_radius !== this.circle_radius) {
   284     if (this.last_circle_radius !== this.circle_radius) {
   287     	if (!this.renderer.renkan.read_only) {
   285     	if (this.renderer.renkan.options.editor_mode) {
   288 	    	this.edit_button.setSectorSize();
   286 	    	this.edit_button.setSectorSize();
   289 	    	this.remove_button.setSectorSize();
   287 	    	this.remove_button.setSectorSize();
   290 	    	this.link_button.setSectorSize();
   288 	    	this.link_button.setSectorSize();
   291 	    }
   289 	    }
   292 	    var square = new paper.Size(this.circle_radius, this.circle_radius),
   290 	    var square = new paper.Size(this.circle_radius, this.circle_radius),
   308     this.title.content = Rkns.Renderer.Utils.shortenText(_text, Rkns.Renderer._NODE_MAX_CHAR);
   306     this.title.content = Rkns.Renderer.Utils.shortenText(_text, Rkns.Renderer._NODE_MAX_CHAR);
   309 
   307 
   310     this.title.position = this.paper_coords.add([0, this.circle_radius + 1.5 *Rkns.Renderer._NODE_FONT_SIZE]);
   308     this.title.position = this.paper_coords.add([0, this.circle_radius + 1.5 *Rkns.Renderer._NODE_FONT_SIZE]);
   311     var _color = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color");
   309     var _color = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color");
   312     this.circle.strokeColor = _color;
   310     this.circle.strokeColor = _color;
   313     this.edit_button.moveTo(this.paper_coords);
   311     if (this.renderer.renkan.options.editor_mode) {
   314     this.remove_button.moveTo(this.paper_coords);
   312     	this.edit_button.moveTo(this.paper_coords);
   315     this.link_button.moveTo(this.paper_coords);
   313 	    this.remove_button.moveTo(this.paper_coords);
       
   314 	    this.link_button.moveTo(this.paper_coords);
       
   315     }
   316     var _img = this.model.get("image");
   316     var _img = this.model.get("image");
   317     if (_img && _img !== this.img) {
   317     if (_img && _img !== this.img) {
   318         var _image = new Image(),
   318         var _image = new Image(),
   319             _this = this;
   319             _this = this;
   320         _image.onload = function() {
   320         _image.onload = function() {
   322                 _this.node_image.remove();
   322                 _this.node_image.remove();
   323             }
   323             }
   324             _this.renderer.node_layer.activate();
   324             _this.renderer.node_layer.activate();
   325             var _ratio = Math.min(2 / _image.width, 2 / _image.height );
   325             var _ratio = Math.min(2 / _image.width, 2 / _image.height );
   326             var _raster = new paper.Raster(_image);
   326             var _raster = new paper.Raster(_image);
   327             if (_this.renderer.renkan.clip_images) {
   327             if (_this.renderer.renkan.options.clip_images) {
   328 	            var _clip = new paper.Path.Circle([0, 0], 1);
   328 	            var _clip = new paper.Path.Circle([0, 0], 1);
   329 	            _raster.scale(_ratio);
   329 	            _raster.scale(_ratio);
   330 	            _this.node_image = new paper.Group(_clip, _raster);
   330 	            _this.node_image = new paper.Group(_clip, _raster);
   331 	            _this.node_image.opacity = .9;
   331 	            _this.node_image.opacity = .9;
   332 	            /* This is a workaround to allow clipping at group level
   332 	            /* This is a workaround to allow clipping at group level
   365     	}
   365     	}
   366     }, this);
   366     }, this);
   367 }
   367 }
   368 
   368 
   369 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   369 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   370 	if (!this.renderer.renkan.read_only) {
   370 	if (this.renderer.renkan.options.editor_mode) {
   371 		this.is_dragging = true;
   371 		if (!this.renderer.renkan.read_only) {
   372 		this.paper_coords = this.paper_coords.add(_delta);
   372 			this.is_dragging = true;
   373     	this.redraw();
   373 			this.paper_coords = this.paper_coords.add(_delta);
       
   374 	    	this.redraw();
       
   375     	}
   374 	} else {
   376 	} else {
   375 		this.renderer.paperShift(_delta);
   377 		this.renderer.paperShift(_delta);
   376 	}
   378 	}
   377 }
   379 }
   378 
   380 
   383     _editor.draw();
   385     _editor.draw();
   384 }
   386 }
   385 
   387 
   386 Rkns.Renderer.Node.prototype.select = function() {
   388 Rkns.Renderer.Node.prototype.select = function() {
   387     this.circle.strokeWidth = 4;
   389     this.circle.strokeWidth = 4;
   388     this.edit_button.show();
   390     if (this.renderer.isEditable()) {
   389     this.remove_button.show();
   391 	    this.edit_button.show();
   390     this.link_button.show();
   392 	    this.remove_button.show();
       
   393 	    this.link_button.show();
       
   394     }
   391     var _uri = this.model.get("uri");
   395     var _uri = this.model.get("uri");
   392     if (_uri) {
   396     if (_uri) {
   393     	Rkns.$('.Rk-Bin-Item').each(function() {
   397     	Rkns.$('.Rk-Bin-Item').each(function() {
   394 	        var _el = Rkns.$(this);
   398 	        var _el = Rkns.$(this);
   395 	        if (_el.attr("data-uri") == _uri) {
   399 	        if (_el.attr("data-uri") == _uri) {
   396 	            _el.addClass("selected");
   400 	            _el.addClass("selected");
   397 	        }
   401 	        }
   398 	    });
   402 	    });
   399     }
   403     }
   400     if (this.renderer.renkan.read_only) {
   404     if (!this.renderer.renkan.options.editor_mode) {
   401         this.openEditor();
   405         this.openEditor();
   402     }
   406     }
   403     this.minimap_circle.fillColor = "#ff00fc";
   407     this.minimap_circle.fillColor = "#ff00fc";
   404 }
   408 }
   405 
   409 
   406 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
   410 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
   407     if (!_newTarget || _newTarget.node_representation !== this) {
   411     if (!_newTarget || _newTarget.node_representation !== this) {
   408         this.edit_button.hide();
   412 	    if (this.renderer.renkan.options.editor_mode) {
   409         this.remove_button.hide();
   413 	        this.edit_button.hide();
   410         this.link_button.hide();
   414 	        this.remove_button.hide();
       
   415 	        this.link_button.hide();
       
   416 	   	}
   411         this.circle.strokeWidth = 2;
   417         this.circle.strokeWidth = 2;
   412         Rkns.$('.Rk-Bin-Item').removeClass("selected");
   418         Rkns.$('.Rk-Bin-Item').removeClass("selected");
   413     	this.minimap_circle.fillColor = this.circle.strokeColor;
   419     	this.minimap_circle.fillColor = this.circle.strokeColor;
   414     }
   420     }
   415 }
   421 }
   434             position: {
   440             position: {
   435                 x: _coords.x,
   441                 x: _coords.x,
   436                 y: _coords.y
   442                 y: _coords.y
   437             }
   443             }
   438         };
   444         };
   439     this.model.set(_data);
   445     if (this.renderer.isEditable()) {
       
   446     	this.model.set(_data);
       
   447     }
   440 }
   448 }
   441 
   449 
   442 Rkns.Renderer.Node.prototype.mouseup = function(_event) {
   450 Rkns.Renderer.Node.prototype.mouseup = function(_event) {
   443     if (!this.renderer.renkan.read_only) {
   451     if (this.renderer.isEditable() && this.renderer.is_dragging) {
   444         if (this.renderer.is_dragging) {
   452         this.saveCoords();
   445             this.saveCoords();
   453     }
   446         }
   454     else {
   447         else {
   455         this.openEditor();
   448             this.openEditor();
       
   449         }
       
   450     }
   456     }
   451     this.renderer.click_target = null;
   457     this.renderer.click_target = null;
   452     this.renderer.is_dragging = false;
   458     this.renderer.is_dragging = false;
   453     this.is_dragging = false;
   459     this.is_dragging = false;
   454 }
   460 }
   455 
   461 
   456 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   462 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   457     this.super("destroy");
   463     this.super("destroy");
   458     this.edit_button.destroy();
   464     if (this.renderer.renkan.options.editor_mode) {
   459     this.remove_button.destroy();
   465 	    this.edit_button.destroy();
   460     this.link_button.destroy();
   466 	    this.remove_button.destroy();
       
   467 	    this.link_button.destroy();
       
   468     }
   461     this.circle.remove();
   469     this.circle.remove();
   462     this.title.remove();
   470     this.title.remove();
   463     this.minimap_circle.remove();
   471     this.minimap_circle.remove();
   464     if (this.node_image) {
   472     if (this.node_image) {
   465         this.node_image.remove();
   473         this.node_image.remove();
   489         fillColor: 'black'
   497         fillColor: 'black'
   490     };
   498     };
   491     this.text.paragraphStyle.justification = 'center';
   499     this.text.paragraphStyle.justification = 'center';
   492     this.text_angle = 0;
   500     this.text_angle = 0;
   493     this.arrow_angle = 0;
   501     this.arrow_angle = 0;
   494     if (this.renderer.renkan.read_only) {
   502     if (this.renderer.renkan.options.editor_mode) {
   495         this.edit_button = new Rkns.Renderer._BaseRepresentation(this.renderer, null);
       
   496         this.remove_button = new Rkns.Renderer._BaseRepresentation(this.renderer, null);
       
   497     } else {
       
   498         this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null);
   503         this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null);
   499         this.edit_button.edge_representation = this;
   504         this.edit_button.edge_representation = this;
   500         this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null);
   505         this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null);
   501         this.remove_button.edge_representation = this;
   506         this.remove_button.edge_representation = this;
   502     }
   507     }
   541     this.text.rotate(_a - this.text_angle);
   546     this.text.rotate(_a - this.text_angle);
   542     var _text = this.model.get("title");
   547     var _text = this.model.get("title");
   543     this.text.content = Rkns.Renderer.Utils.shortenText(_text, Rkns.Renderer._EDGE_MAX_CHAR);
   548     this.text.content = Rkns.Renderer.Utils.shortenText(_text, Rkns.Renderer._EDGE_MAX_CHAR);
   544     this.text.position = this.paper_coords.add(_textdelta);
   549     this.text.position = this.paper_coords.add(_textdelta);
   545     this.text_angle = _a;
   550     this.text_angle = _a;
   546     this.edit_button.moveTo(this.paper_coords);
   551     if (this.renderer.renkan.options.editor_mode) {
   547     this.remove_button.moveTo(this.paper_coords);
   552 	    this.edit_button.moveTo(this.paper_coords);
       
   553 	    this.remove_button.moveTo(this.paper_coords);
       
   554     }
   548 }
   555 }
   549 
   556 
   550 Rkns.Renderer.Edge.prototype.openEditor = function() {
   557 Rkns.Renderer.Edge.prototype.openEditor = function() {
   551     this.renderer.removeRepresentationsOfType("editor");
   558     this.renderer.removeRepresentationsOfType("editor");
   552     var _editor = this.renderer.addRepresentation("EdgeEditor",null);
   559     var _editor = this.renderer.addRepresentation("EdgeEditor",null);
   554     _editor.draw();
   561     _editor.draw();
   555 }
   562 }
   556 
   563 
   557 Rkns.Renderer.Edge.prototype.select = function() {
   564 Rkns.Renderer.Edge.prototype.select = function() {
   558     this.line.strokeWidth = 4;
   565     this.line.strokeWidth = 4;
   559     this.edit_button.show();
   566     if (this.renderer.isEditable()) {
   560     this.remove_button.show();
   567 	    this.edit_button.show();
   561     if (this.renderer.renkan.read_only) {
   568 	    this.remove_button.show();
       
   569    	}
       
   570     if (!this.renderer.renkan.options.editor_mode) {
   562         this.openEditor();
   571         this.openEditor();
   563     }
   572     }
   564 }
   573 }
   565 
   574 
   566 Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
   575 Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
   567     if (!_newTarget || _newTarget.edge_representation !== this) {
   576     if (!_newTarget || _newTarget.edge_representation !== this) {
   568         this.edit_button.hide();
   577     	if (this.renderer.renkan.options.editor_mode) {
   569         this.remove_button.hide();
   578 	        this.edit_button.hide();
       
   579 	        this.remove_button.hide();
       
   580         }
   570         this.line.strokeWidth = 2;
   581         this.line.strokeWidth = 2;
   571     }
   582     }
   572 }
   583 }
   573 
   584 
   574 Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
   585 Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
   583     this.renderer.click_target = null;
   594     this.renderer.click_target = null;
   584     this.renderer.is_dragging = false;
   595     this.renderer.is_dragging = false;
   585 }
   596 }
   586 
   597 
   587 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   598 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   588 	if (!this.renderer.renkan.read_only) {
   599 	if (this.renderer.renkan.options.editor_mode) {
   589 	    this.from_representation.paperShift(_delta);
   600 		if (!this.renderer.renkan.options.read_only) {
   590 	    this.to_representation.paperShift(_delta);
   601 		    this.from_representation.paperShift(_delta);
       
   602 		    this.to_representation.paperShift(_delta);
       
   603 	    }
   591 	} else {
   604 	} else {
   592 		this.renderer.paperShift(_delta);
   605 		this.renderer.paperShift(_delta);
   593 	}
   606 	}
   594 }
   607 }
   595 
   608 
   596 Rkns.Renderer.Edge.prototype.destroy = function() {
   609 Rkns.Renderer.Edge.prototype.destroy = function() {
   597     this.super("destroy");
   610     this.super("destroy");
   598     this.line.remove();
   611     this.line.remove();
   599     this.arrow.remove();
   612     this.arrow.remove();
   600     this.text.remove();
   613     this.text.remove();
   601     this.edit_button.destroy();
   614     if (this.renderer.renkan.options.editor_mode) {
   602     this.remove_button.destroy();
   615 	    this.edit_button.destroy();
       
   616 	    this.remove_button.destroy();
       
   617    	}
   603     var _this = this;
   618     var _this = this;
   604     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   619     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   605         return _edge === _this;
   620         return _edge === _this;
   606     });
   621     });
   607 }
   622 }
   637     this.arrow.position = _c;
   652     this.arrow.position = _c;
   638     this.arrow_angle = _a;
   653     this.arrow_angle = _a;
   639 }
   654 }
   640 
   655 
   641 Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) {
   656 Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) {
       
   657 	if (!this.renderer.isEditable()) {
       
   658 		this.renderer.removeRepresentation(_this);
       
   659     	paper.view.draw();
       
   660     	return;
       
   661 	}
   642     this.end_pos = this.end_pos.add(_delta);
   662     this.end_pos = this.end_pos.add(_delta);
   643     var _hitResult = paper.project.hitTest(this.end_pos);
   663     var _hitResult = paper.project.hitTest(this.end_pos);
   644     this.renderer.findTarget(_hitResult);
   664     this.renderer.findTarget(_hitResult);
   645     this.redraw();
   665     this.redraw();
   646 }
   666 }
   656                 id: Rkns.Utils.getUID('edge'),
   676                 id: Rkns.Utils.getUID('edge'),
   657                 created_by: this.renderer.renkan.current_user,
   677                 created_by: this.renderer.renkan.current_user,
   658                 from: _model.get("_id"),
   678                 from: _model.get("_id"),
   659                 to: _target.model.get("_id")
   679                 to: _target.model.get("_id")
   660             };
   680             };
   661             this.project.addEdge(_data);
   681             if (this.renderer.isEditable()) {
       
   682             	this.project.addEdge(_data);
       
   683             }
   662         }
   684         }
   663         if (_model === _target.model || (_target.node_representation && _target.node_representation.model === _model)) {
   685         if (_model === _target.model || (_target.node_representation && _target.node_representation.model === _model)) {
   664             _endDrag = false;
   686             _endDrag = false;
   665             this.renderer.is_dragging = true;
   687             this.renderer.is_dragging = true;
   666         }
   688         }
   724 );
   746 );
   725 
   747 
   726 Rkns.Renderer.NodeEditor.prototype.draw = function() {
   748 Rkns.Renderer.NodeEditor.prototype.draw = function() {
   727     var _model = this.node_representation.model,
   749     var _model = this.node_representation.model,
   728         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER,
   750         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER,
   729         _template = (this.renderer.renkan.read_only ? this.readOnlyTemplate : this.template),
   751         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate ),
   730         _image_placeholder = this.renderer.renkan.static_url + "img/image-placeholder.png",
   752         _image_placeholder = this.renderer.renkan.options.static_url + "img/image-placeholder.png",
   731         _size = (_model.get("size") || 0);
   753         _size = (_model.get("size") || 0);
   732     this.editor_$
   754     this.editor_$
   733         .html(_template({
   755         .html(_template({
   734             node: {
   756             node: {
   735                 title: _model.get("title"),
   757                 title: _model.get("title"),
   744                 size: (_size > 0 ? "+" : "") + _size
   766                 size: (_size > 0 ? "+" : "") + _size
   745             },
   767             },
   746             translate: this.renderer.renkan.translate
   768             translate: this.renderer.renkan.translate
   747         }));
   769         }));
   748     this.redraw();
   770     this.redraw();
   749     var _this = this;
   771     var _this = this,
   750     this.editor_$.find(".Rk-CloseX").click(function() {
   772     	closeEditor = function() {
   751         _this.renderer.removeRepresentation(_this);
   773     		_this.renderer.removeRepresentation(_this);
   752         paper.view.draw();
   774         	paper.view.draw();
   753     });
   775     	}
   754     if (!this.renderer.renkan.read_only) {
   776     	
       
   777     this.editor_$.find(".Rk-CloseX").click(closeEditor);
       
   778     
       
   779     if (this.renderer.isEditable()) {
   755     	
   780     	
   756     	var onFieldChange = Rkns._(function() {
   781     	var onFieldChange = Rkns._(function() {
   757     		Rkns._(function() {
   782     		Rkns._(function() {
   758 	            var _uri = _this.editor_$.find(".Rk-Edit-URI").val(),
   783 	            if (_this.renderer.isEditable()) {
   759 	                _image = _this.editor_$.find(".Rk-Edit-Image").val();
   784 		            var _uri = _this.editor_$.find(".Rk-Edit-URI").val(),
   760 	            _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image || _image_placeholder);
   785 		                _image = _this.editor_$.find(".Rk-Edit-Image").val();
   761 	            _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri);
   786 		            _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image || _image_placeholder);
   762 	            var _data = {
   787 		            _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri);
   763 	                title: _this.editor_$.find(".Rk-Edit-Title").val(),
   788 		            var _data = {
   764 	                description: _this.editor_$.find(".Rk-Edit-Description").val(),
   789 		                title: _this.editor_$.find(".Rk-Edit-Title").val(),
   765 	                uri: _uri,
   790 		                description: _this.editor_$.find(".Rk-Edit-Description").val(),
   766 	                image: _image
   791 		                uri: _uri,
       
   792 		                image: _image
       
   793 		            }
       
   794 	            	_model.set(_data);
       
   795 	            	_this.redraw();
       
   796 	            } else {
       
   797 	            	closeEditor();
   767 	            }
   798 	            }
   768 	            _model.set(_data);
   799 	            
   769 	            _this.redraw();
       
   770     		}).defer();
   800     		}).defer();
   771     	}).throttle(500);
   801     	}).throttle(500);
   772     	
   802     	
   773     	this.editor_$.find("input, textarea").bind("change keyup paste", onFieldChange);
   803     	this.editor_$.find("input, textarea").bind("change keyup paste", onFieldChange);
   774     	
   804     	
   798         );
   828         );
   799         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
   829         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
   800             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
   830             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
   801             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color")) }
   831             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color")) }
   802         ).click(function() {
   832         ).click(function() {
   803             _model.set("color", $(this).attr("data-color"));
   833             if (_this.renderer.isEditable()) {
   804             paper.view.draw();
   834 	            _model.set("color", $(this).attr("data-color"));
       
   835 				paper.view.draw();
       
   836             } else {
       
   837             	closeEditor();
       
   838             }
   805         });
   839         });
   806         
   840         
   807         function shiftSize(n) {
   841         function shiftSize(n) {
   808         	var _newsize = n+(_model.get("size") || 0);
   842         	if (_this.renderer.isEditable()) {
   809         	_this.editor_$.find(".Rk-Edit-Size-Value").text((_newsize > 0 ? "+" : "") + _newsize);
   843 	        	var _newsize = n+(_model.get("size") || 0);
   810         	_model.set("size", _newsize);
   844 	        	_this.editor_$.find(".Rk-Edit-Size-Value").text((_newsize > 0 ? "+" : "") + _newsize);
   811 			paper.view.draw();
   845 	        	_model.set("size", _newsize);
       
   846 				paper.view.draw();
       
   847 			} else {
       
   848 				closeEditor();
       
   849 			}
   812         }
   850         }
   813         
   851         
   814         this.editor_$.find(".Rk-Edit-Size-Down").click(function() {
   852         this.editor_$.find(".Rk-Edit-Size-Down").click(function() {
   815         	shiftSize(-1);
   853         	shiftSize(-1);
   816         	return false;
   854         	return false;
   890 Rkns.Renderer.EdgeEditor.prototype.draw = function() {
   928 Rkns.Renderer.EdgeEditor.prototype.draw = function() {
   891     var _model = this.edge_representation.model,
   929     var _model = this.edge_representation.model,
   892         _from_model = _model.get("from"),
   930         _from_model = _model.get("from"),
   893         _to_model = _model.get("to"),
   931         _to_model = _model.get("to"),
   894         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER,
   932         _created_by = _model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER,
   895         _template = (this.renderer.renkan.read_only ? this.readOnlyTemplate : this.template);
   933         _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate);
   896     this.editor_$
   934     this.editor_$
   897         .html(_template({
   935         .html(_template({
   898             edge: {
   936             edge: {
   899                 title: _model.get("title"),
   937                 title: _model.get("title"),
   900                 uri: _model.get("uri"),
   938                 uri: _model.get("uri"),
   907                 to_color: _to_model.get("color") || (_to_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color"),
   945                 to_color: _to_model.get("color") || (_to_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color"),
   908                 created_by_color: _created_by.get("color"),
   946                 created_by_color: _created_by.get("color"),
   909                 created_by_title: _created_by.get("title")
   947                 created_by_title: _created_by.get("title")
   910             },
   948             },
   911             translate: this.renderer.renkan.translate,
   949             translate: this.renderer.renkan.translate,
   912             properties: this.renderer.renkan.properties
   950             properties: this.renderer.renkan.options.properties
   913         }));
   951         }));
   914     this.redraw();
   952     this.redraw();
   915     var _this = this;
   953     var _this = this,
   916     this.editor_$.find(".Rk-CloseX").click(function() {
   954     	closeEditor = function() {
   917         _this.renderer.removeRepresentation(_this);
   955 	        _this.renderer.removeRepresentation(_this);
   918         paper.view.draw();
   956 	        paper.view.draw();
   919     });
   957     	}
   920     if (!this.renderer.renkan.read_only) {
   958     this.editor_$.find(".Rk-CloseX").click(closeEditor);
       
   959     
       
   960     if (this.renderer.isEditable()) {
   921     	
   961     	
   922     	var onFieldChange = Rkns._(function() {
   962     	var onFieldChange = Rkns._(function() {
   923     		Rkns._(function() {
   963     		Rkns._(function() {
   924     			_this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val());
   964     			if (_this.renderer.isEditable()) {
   925 	            var _data = {
   965 	    			_this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val());
   926 	                title: _this.editor_$.find(".Rk-Edit-Title").val(),
   966 		            var _data = {
   927 	                uri: _this.editor_$.find(".Rk-Edit-URI").val()
   967 		                title: _this.editor_$.find(".Rk-Edit-Title").val(),
   928 	            }
   968 		                uri: _this.editor_$.find(".Rk-Edit-URI").val()
   929 	            _model.set(_data);
   969 		            }
   930 	            paper.view.draw();
   970 		            _model.set(_data);
       
   971 		            paper.view.draw();
       
   972 	           	} else {
       
   973 	           		closeEditor();
       
   974 	           	}
   931     		}).defer();
   975     		}).defer();
   932     	}).throttle(500);
   976     	}).throttle(500);
   933     	
   977     	
   934         this.editor_$.find("input").bind("keyup change paste", onFieldChange);
   978         this.editor_$.find("input").bind("keyup change paste", onFieldChange);
   935         this.editor_$.find(".Rk-Edit-Vocabulary").change(function() {
   979         this.editor_$.find(".Rk-Edit-Vocabulary").change(function() {
   940         		_this.editor_$.find(".Rk-Edit-URI").val(v);
   984         		_this.editor_$.find(".Rk-Edit-URI").val(v);
   941         		onFieldChange();
   985         		onFieldChange();
   942         	}
   986         	}
   943         });
   987         });
   944         this.editor_$.find(".Rk-Edit-Direction").click(function() {
   988         this.editor_$.find(".Rk-Edit-Direction").click(function() {
   945         	_model.set({
   989 			if (_this.renderer.isEditable()) {
   946         		from: _model.get("to"),
   990 	        	_model.set({
   947         		to: _model.get("from")
   991 	        		from: _model.get("to"),
   948         	});
   992 	        		to: _model.get("from")
   949         	_this.draw();
   993 	        	});
       
   994 	        	_this.draw();
       
   995 	       	} else {
       
   996 	       		closeEditor();
       
   997 	       	}
   950         });
   998         });
   951         this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(
   999         this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover(
   952             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").show(); },
  1000             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").show(); },
   953             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").hide(); }
  1001             function() { _this.editor_$.find(".Rk-Edit-ColorPicker").hide(); }
   954         );
  1002         );
   955         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
  1003         this.editor_$.find(".Rk-Edit-ColorPicker li").hover(
   956             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
  1004             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); },
   957             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color")); }
  1005             function() { _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color")); }
   958         ).click(function() {
  1006         ).click(function() {
   959             _model.set("color", $(this).attr("data-color"));
  1007 			if (_this.renderer.isEditable()) {
   960             paper.view.draw();
  1008             	_model.set("color", $(this).attr("data-color"));
       
  1009             	paper.view.draw();
       
  1010             } else {
       
  1011 	       		closeEditor();
       
  1012 	       	}
   961         });
  1013         });
   962     }
  1014     }
   963 }
  1015 }
   964 
  1016 
   965 Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
  1017 Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
   987 	var sectorInner = this.node_representation.circle_radius;
  1039 	var sectorInner = this.node_representation.circle_radius;
   988 	if (sectorInner !== this.lastSectorInner) {
  1040 	if (sectorInner !== this.lastSectorInner) {
   989 		if (this.sector) {
  1041 		if (this.sector) {
   990 			this.sector.destroy();
  1042 			this.sector.destroy();
   991 		}
  1043 		}
   992 		this.sector = Rkns.Renderer.Utils.sector(this, 1 + sectorInner, Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner, - 90, 30, 1, this.renderer.renkan.static_url+'img/edit.png', this.renderer.renkan.translate("Edit"));
  1044 		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"));
   993 		this.lastSectorInner = sectorInner;
  1045 		this.lastSectorInner = sectorInner;
   994 	}
  1046 	}
   995 }
  1047 }
   996 
  1048 
   997 Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
  1049 Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
  1040 	var sectorInner = this.node_representation.circle_radius;
  1092 	var sectorInner = this.node_representation.circle_radius;
  1041 	if (sectorInner !== this.lastSectorInner) {
  1093 	if (sectorInner !== this.lastSectorInner) {
  1042 		if (this.sector) {
  1094 		if (this.sector) {
  1043 			this.sector.destroy();
  1095 			this.sector.destroy();
  1044 		}
  1096 		}
  1045 		this.sector = Rkns.Renderer.Utils.sector(this, 1 + sectorInner, Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner, - 210, - 90, 1, this.renderer.renkan.static_url+'img/remove.png', this.renderer.renkan.translate("Remove"));
  1097 		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"));
  1046 		this.lastSectorInner = sectorInner;
  1098 		this.lastSectorInner = sectorInner;
  1047 	}
  1099 	}
  1048 }
  1100 }
  1049 
  1101 
  1050 Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
  1102 Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
  1070     }
  1122     }
  1071 }
  1123 }
  1072 
  1124 
  1073 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
  1125 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
  1074     this.renderer.removeRepresentationsOfType("editor");
  1126     this.renderer.removeRepresentationsOfType("editor");
  1075     if (confirm(this.renderer.renkan.translate('Do you really wish to remove node ') + '"' + this.node_representation.model.get("title") + '"?')) {
  1127     if (this.renderer.isEditable() && confirm(this.renderer.renkan.translate('Do you really wish to remove node ') + '"' + this.node_representation.model.get("title") + '"?')) {
  1076         this.project.removeNode(this.node_representation.model);
  1128         this.project.removeNode(this.node_representation.model);
  1077     }
  1129     }
  1078 }
  1130 }
  1079 
  1131 
  1080 Rkns.Renderer.NodeRemoveButton.prototype.destroy = function() {
  1132 Rkns.Renderer.NodeRemoveButton.prototype.destroy = function() {
  1094 	var sectorInner = this.node_representation.circle_radius;
  1146 	var sectorInner = this.node_representation.circle_radius;
  1095 	if (sectorInner !== this.lastSectorInner) {
  1147 	if (sectorInner !== this.lastSectorInner) {
  1096 		if (this.sector) {
  1148 		if (this.sector) {
  1097 			this.sector.destroy();
  1149 			this.sector.destroy();
  1098 		}
  1150 		}
  1099 		this.sector = Rkns.Renderer.Utils.sector(this, 1 + sectorInner, Rkns.Renderer._NODE_BUTTON_WIDTH + sectorInner, 30, 150, 1, this.renderer.renkan.static_url+'img/link.png', this.renderer.renkan.translate("Link to another node"));
  1151 		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"));
  1100 		this.lastSectorInner = sectorInner;
  1152 		this.lastSectorInner = sectorInner;
  1101 	}
  1153 	}
  1102 }
  1154 }
  1103 
  1155 
  1104 Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
  1156 Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
  1132 
  1184 
  1133 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1185 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1134 
  1186 
  1135 Rkns.Renderer.EdgeEditButton.prototype._init = function() {
  1187 Rkns.Renderer.EdgeEditButton.prototype._init = function() {
  1136     this.type = "Edge-edit-button";
  1188     this.type = "Edge-edit-button";
  1137     this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 90, 90, 1, this.renderer.renkan.static_url+'img/edit.png', this.renderer.renkan.translate("Edit"));
  1189     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"));
  1138 }
  1190 }
  1139 
  1191 
  1140 Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) {
  1192 Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) {
  1141     this.sector.moveTo(_pos);
  1193     this.sector.moveTo(_pos);
  1142 }
  1194 }
  1174 
  1226 
  1175 Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1227 Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
  1176 
  1228 
  1177 Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
  1229 Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
  1178     this.type = "Edge-remove-button";
  1230     this.type = "Edge-remove-button";
  1179     this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 270, -90, 1, this.renderer.renkan.static_url+'img/remove.png', this.renderer.renkan.translate("Remove"));
  1231     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"));
  1180 }
  1232 }
  1181 Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) {
  1233 Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) {
  1182     this.sector.moveTo(_pos);
  1234     this.sector.moveTo(_pos);
  1183 }
  1235 }
  1184 
  1236 
  1201     }
  1253     }
  1202 }
  1254 }
  1203 
  1255 
  1204 Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
  1256 Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
  1205     this.renderer.removeRepresentationsOfType("editor");
  1257     this.renderer.removeRepresentationsOfType("editor");
  1206     if (confirm(this.renderer.renkan.translate('Do you really wish to remove edge ') + '"' + this.edge_representation.model.get("title") + '"?')) {
  1258     if (this.renderer.isEditable() && confirm(this.renderer.renkan.translate('Do you really wish to remove edge ') + '"' + this.edge_representation.model.get("title") + '"?')) {
  1207         this.project.removeEdge(this.edge_representation.model);
  1259         this.project.removeEdge(this.edge_representation.model);
  1208     }
  1260     }
  1209 }
  1261 }
  1210 
  1262 
  1211 Rkns.Renderer.EdgeRemoveButton.prototype.destroy = function() {
  1263 Rkns.Renderer.EdgeRemoveButton.prototype.destroy = function() {
  1313     });
  1365     });
  1314     this.canvas_$.on("drop", function(_event) {
  1366     this.canvas_$.on("drop", function(_event) {
  1315     	_event.stopPropagation();
  1367     	_event.stopPropagation();
  1316     	_event.preventDefault();
  1368     	_event.preventDefault();
  1317     	_allowScroll = true;
  1369     	_allowScroll = true;
  1318     	if (_this.renkan.read_only) {
  1370     	if (!_this.isEditable()) {
  1319     		return;
  1371     		return;
  1320     	}
  1372     	}
  1321     	var res = {}
  1373     	var res = {}
  1322     	if (_event.originalEvent.dataTransfer.types) {
  1374     	if (_event.originalEvent.dataTransfer.types) {
  1323     		Rkns._(_event.originalEvent.dataTransfer.types).each(function(t) {
  1375     		Rkns._(_event.originalEvent.dataTransfer.types).each(function(t) {
  1390 		    		newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
  1442 		    		newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
  1391 		    		newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
  1443 		    		newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
  1392 		    		newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
  1444 		    		newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
  1393 		    	}
  1445 		    	}
  1394     	}
  1446     	}
  1395 /*
       
  1396     	var fields = ["title", "description", "uri", "image"];
       
  1397     	for (var i = 0; i < fields.length; i++) {
       
  1398     		var f = fields[i];
       
  1399     		if (res["text/x-iri-" + f]) {
       
  1400     			newNode[f] = res["text/x-iri-" + f];
       
  1401     		}
       
  1402     	}
       
  1403 */
       
  1404     	if (newNode.title || newNode.description || newNode.uri) {
  1447     	if (newNode.title || newNode.description || newNode.uri) {
  1405     		var _off = _this.canvas_$.offset(),
  1448     		var _off = _this.canvas_$.offset(),
  1406             _point = new paper.Point([
  1449             _point = new paper.Point([
  1407                 _event.originalEvent.pageX - _off.left,
  1450                 _event.originalEvent.pageX - _off.left,
  1408                 _event.originalEvent.pageY - _off.top
  1451                 _event.originalEvent.pageY - _off.top
  1573     	_this.rescaleMinimap()
  1616     	_this.rescaleMinimap()
  1574     }, 2000);
  1617     }, 2000);
  1575 }
  1618 }
  1576 
  1619 
  1577 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
  1620 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
  1578     '<div class="Rk-TopBar"><% if (read_only) { %><h2 class="Rk-PadTitle"><%- project.get("title") || translate("Untitled project")%></h2>'
  1621     '<div class="Rk-TopBar"><% if (!options.editor_mode) { %><h2 class="Rk-PadTitle"><%- project.get("title") || translate("Untitled project")%></h2>'
  1579     + '<% } else { %><input type="text" class="Rk-PadTitle" value="<%- project.get("title") || "" %>" placeholder="<%-translate("Untitled project")%>" /><% } %>'
  1622     + '<% } else { %><input type="text" class="Rk-PadTitle" value="<%- project.get("title") || "" %>" placeholder="<%-translate("Untitled project")%>" /><% } %>'
  1580     + '<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>'
  1623     + '<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>'
  1581     + '<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>'
  1624     + '<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>'
  1582     + '<% if (!read_only) { %>'
  1625     + '<% if (options.editor_mode) { %>'
  1583     + '<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>'
  1626     + '<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>'
  1584     + '<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>'
  1627     + '<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>'
  1585     + '<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>'
  1628     + '<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>'
  1586     + '<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">'
  1629     + '<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">'
  1587     + '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a>'
  1630     + '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a>'
  1588     + '<div class="Rk-TopBar-Separator"></div></div>'
  1631     + '<div class="Rk-TopBar-Separator"></div></div>'
  1589     + '<% } %>'
  1632     + '<% } %>'
  1590     + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
  1633     + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
  1591     + '<% if (show_bins) { %><div class="Rk-Fold-Bins">&laquo;</div><% } %>'
  1634     + '<% if (options.show_bins) { %><div class="Rk-Fold-Bins">&laquo;</div><% } %>'
  1592     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div></div>'
  1635     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div></div>'
  1593     + '</div>'
  1636     + '</div>'
  1594 );
  1637 );
  1595 
  1638 
  1596 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
  1639 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
  1615         this.bundles.push(_bundle);
  1658         this.bundles.push(_bundle);
  1616     }
  1659     }
  1617     return _bundle;
  1660     return _bundle;
  1618 }
  1661 }
  1619 
  1662 
       
  1663 Rkns.Renderer.Scene.prototype.isEditable = function() {
       
  1664 	return (this.renkan.options.editor_mode && !this.renkan.read_only)
       
  1665 }
       
  1666 
  1620 Rkns.Renderer.Scene.prototype.onStatusChange = function() {
  1667 Rkns.Renderer.Scene.prototype.onStatusChange = function() {
  1621 	var savebtn = this.$.find(".Rk-Save-Button"),
  1668 	var savebtn = this.$.find(".Rk-Save-Button"),
  1622 		tip = savebtn.find(".Rk-TopBar-Tooltip-Contents");
  1669 		tip = savebtn.find(".Rk-TopBar-Tooltip-Contents");
  1623 	if (this.renkan.read_only) {
  1670 	if (this.renkan.read_only) {
  1624 		savebtn.removeClass("disabled Rk-Save-Online").addClass("Rk-Save-ReadOnly");
  1671 		savebtn.removeClass("disabled Rk-Save-Online").addClass("Rk-Save-ReadOnly");
  1625 		tip.text(this.renkan.translate("Connection lost"));
  1672 		tip.text(this.renkan.translate("Connection lost"));
  1626 	} else {
  1673 	} else {
  1627 		if (this.renkan.snapshot_mode) {
  1674 		if (this.renkan.options.snapshot_mode) {
  1628 			savebtn.removeClass("Rk-Save-ReadOnly Rk-Save-Online");
  1675 			savebtn.removeClass("Rk-Save-ReadOnly Rk-Save-Online");
  1629 			tip.text(this.renkan.translate("Archive Project"));
  1676 			tip.text(this.renkan.translate("Archive Project"));
  1630 		} else {
  1677 		} else {
  1631 			savebtn.removeClass("disabled Rk-Save-ReadOnly").addClass("Rk-Save-Online");
  1678 			savebtn.removeClass("disabled Rk-Save-ReadOnly").addClass("Rk-Save-Online");
  1632 			tip.text(this.renkan.translate("Auto-save enabled"));
  1679 			tip.text(this.renkan.translate("Auto-save enabled"));
  1803 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
  1850 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
  1804     if (!this.click_target || this.click_target.type !== "temp-edge") {
  1851     if (!this.click_target || this.click_target.type !== "temp-edge") {
  1805         this.removeRepresentationsOfType("editor");
  1852         this.removeRepresentationsOfType("editor");
  1806         this.is_dragging = false;
  1853         this.is_dragging = false;
  1807         var _hitResult = paper.project.hitTest(_event.point);
  1854         var _hitResult = paper.project.hitTest(_event.point);
  1808         if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
  1855         if (this.isEditable() && _hitResult && typeof _hitResult.item.__representation !== "undefined") {
  1809             this.click_target = _hitResult.item.__representation;
  1856             this.click_target = _hitResult.item.__representation;
  1810             if (this.click_target.type === "Node-link-button") {
  1857             if (this.click_target.type === "Node-link-button") {
  1811                 this.removeRepresentationsOfType("editor");
  1858                 this.removeRepresentationsOfType("editor");
  1812                 this.addTempEdge(this.click_target.node_representation, _event.point);
  1859                 this.addTempEdge(this.click_target.node_representation, _event.point);
  1813             }
  1860             }
  1814         } else {
  1861         } else {
  1815             this.click_target = null;
  1862             this.click_target = null;
  1816             if (this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
  1863             if (this.isEditable() && this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
  1817                 var _coords = this.toModelCoords(_event.point),
  1864                 var _coords = this.toModelCoords(_event.point),
  1818                     _data = {
  1865                     _data = {
  1819                         id: Rkns.Utils.getUID('node'),
  1866                         id: Rkns.Utils.getUID('node'),
  1820                         created_by: this.renkan.current_user,
  1867                         created_by: this.renkan.current_user,
  1821                         position: {
  1868                         position: {
  1827                 this.getRepresentationByModel(_node).openEditor();
  1874                 this.getRepresentationByModel(_node).openEditor();
  1828             }
  1875             }
  1829         }
  1876         }
  1830     }
  1877     }
  1831     if (this.click_mode) {
  1878     if (this.click_mode) {
  1832         if (this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === "Node") {
  1879         if (this.isEditable() && this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === "Node") {
  1833             this.removeRepresentationsOfType("editor");
  1880             this.removeRepresentationsOfType("editor");
  1834             this.addTempEdge(this.click_target, _event.point);
  1881             this.addTempEdge(this.click_target, _event.point);
  1835             this.click_mode = Rkns.Renderer._CLICKMODE_ENDEDGE;
  1882             this.click_mode = Rkns.Renderer._CLICKMODE_ENDEDGE;
  1836             this.notif_$.fadeOut(function() {
  1883             this.notif_$.fadeOut(function() {
  1837                 Rkns.$(this).html(_renkan.translate("Click on a second node to complete the edge")).fadeIn();
  1884                 Rkns.$(this).html(_renkan.translate("Click on a second node to complete the edge")).fadeIn();
  1884         this.redraw();
  1931         this.redraw();
  1885     }
  1932     }
  1886 }
  1933 }
  1887 
  1934 
  1888 Rkns.Renderer.Scene.prototype.onDoubleClick = function(_event) {
  1935 Rkns.Renderer.Scene.prototype.onDoubleClick = function(_event) {
  1889     if (this.renkan.read_only) {
  1936     if (!this.isEditable()) {
  1890         return;
  1937         return;
  1891     }
  1938     }
  1892     var _off = this.canvas_$.offset(),
  1939     var _off = this.canvas_$.offset(),
  1893         _point = new paper.Point([
  1940         _point = new paper.Point([
  1894             _event.pageX - _off.left,
  1941             _event.pageX - _off.left,
  1895             _event.pageY - _off.top
  1942             _event.pageY - _off.top
  1896         ]);
  1943         ]);
  1897     var _hitResult = paper.project.hitTest(_point);
  1944     var _hitResult = paper.project.hitTest(_point);
  1898     if (!_hitResult || typeof _hitResult.item.__representation === "undefined") {
  1945     if (this.isEditable() && (!_hitResult || typeof _hitResult.item.__representation === "undefined")) {
  1899         var _coords = this.toModelCoords(_point),
  1946         var _coords = this.toModelCoords(_point),
  1900             _data = {
  1947             _data = {
  1901                 id: Rkns.Utils.getUID('node'),
  1948                 id: Rkns.Utils.getUID('node'),
  1902                 created_by: this.renkan.current_user,
  1949                 created_by: this.renkan.current_user,
  1903                 position: {
  1950                 position: {