diff -r 7e132e2a48ca -r 267d67791e05 server/src/main/webapp/static/js/paper-renderer.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/src/main/webapp/static/js/paper-renderer.js Tue Dec 25 21:29:11 2012 +0100 @@ -0,0 +1,1400 @@ +Rkns.Renderer = { + _MARGIN_X: 80, + _MARGIN_Y: 50, + _MIN_DRAG_DISTANCE: 2, + _NODE_RADIUS: 25, + _NODE_BUTTON_INNER: 26, + _NODE_BUTTON_OUTER: 60, + _EDGE_BUTTON_INNER: 1, + _EDGE_BUTTON_OUTER: 40, + _NODE_FONT_SIZE: 10, + _EDGE_FONT_SIZE: 9, + _NODE_MAX_CHAR: 50, + _EDGE_MAX_CHAR: 40, + _ARROW_LENGTH: 16, + _ARROW_WIDTH: 8, + _EDITOR_ARROW_LENGTH : 20, + _EDITOR_ARROW_WIDTH : 40, + _EDITOR_MARGIN : 15, + _EDITOR_PADDING : 10, + _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0']), + _CLICKMODE_ADDNODE : 1, + _CLICKMODE_STARTEDGE : 2, + _CLICKMODE_ENDEDGE : 3 +} + +Rkns.Renderer.Utils = { + drawEditBox : function(_coords, _path, _width, _xmargin, _selector) { + _selector.css({ + width: (_width - 2* Rkns.Renderer._EDITOR_PADDING), + }) + var _height = _selector.outerHeight() + 2* Rkns.Renderer._EDITOR_PADDING, + _isLeft = (_coords.x < paper.view.center.x ? 1 : -1), + _left = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._EDITOR_ARROW_LENGTH ), + _right = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._EDITOR_ARROW_LENGTH + _width ), + _top = _coords.y - _height / 2; + if (_top < Rkns.Renderer._EDITOR_MARGIN) { + _top = Math.min( Rkns.Renderer._EDITOR_MARGIN, _coords.y - Rkns.Renderer._EDITOR_ARROW_WIDTH / 2 ); + } + var _bottom = _top + _height; + if (_bottom > (paper.view.size.height - Rkns.Renderer._EDITOR_MARGIN)) { + _bottom = Math.max( paper.view.size.height - Rkns.Renderer._EDITOR_MARGIN, _coords.y + Rkns.Renderer._EDITOR_ARROW_WIDTH / 2 ); + _top = _bottom - _height; + } + _path.segments[0].point + = _path.segments[7].point + = _coords.add([_isLeft * _xmargin, 0]); + _path.segments[1].point.x + = _path.segments[2].point.x + = _path.segments[5].point.x + = _path.segments[6].point.x + = _left; + _path.segments[3].point.x + = _path.segments[4].point.x + = _right; + _path.segments[2].point.y + = _path.segments[3].point.y + = _top; + _path.segments[4].point.y + = _path.segments[5].point.y + = _bottom; + _path.segments[1].point.y = _coords.y - Rkns.Renderer._EDITOR_ARROW_WIDTH / 2; + _path.segments[6].point.y = _coords.y + Rkns.Renderer._EDITOR_ARROW_WIDTH / 2; + _path.closed = true; + _path.fillColor = new paper.GradientColor(Rkns.Renderer._EDITOR_GRADIENT, [0,_top], [0, _bottom]); + _selector.css({ + left: (Rkns.Renderer._EDITOR_PADDING + Math.min(_left, _right)), + top: (Rkns.Renderer._EDITOR_PADDING + _top) + }); + }, + sector : function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgsrc, _caption) { + var _startRads = _startAngle * Math.PI / 180, + _endRads = _endAngle * Math.PI / 180, + _img = new Image(), + _span = _endRads - _startRads, + _k = .0879 * _span, + _kin = _k * _inR, + _kout = _k * _outR, + _startdx = - Math.sin(_startRads), + _startdy = Math.cos(_startRads), + _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx, + _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy, + _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx, + _startYOut = Math.sin(_startRads) * _outR + _padding * _startdy, + _enddx = - Math.sin(_endRads), + _enddy = Math.cos(_endRads), + _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx, + _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy, + _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx, + _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy, + _centerR = (_inR + _outR)/2, + _centerRads = (_startRads + _endRads) / 2, + _centerX = Math.cos(_centerRads) * _centerR, + _centerY = Math.sin(_centerRads) * _centerR, + _textX = Math.cos(_centerRads) * (_outR + 3), + _textY = Math.sin(_centerRads) * (_outR + 3), + _segments = []; + _segments.push([[_startXIn, _startYIn], [0, 0], [ _kin * _startdx, _kin * _startdy ]]); + for (var i = 1; i < 4; i++) { + var _rads = i * _span / 4 + _startRads, + _dx = - Math.sin(_rads), + _dy = Math.cos(_rads), + _x = Math.cos(_rads) * _inR, + _y = Math.sin(_rads) * _inR; + _segments.push([[_x, _y], [ - _kin * _dx, - _kin * _dy], [ _kin * _dx, _kin * _dy ]]); + } + _segments.push([[_endXIn, _endYIn], [ - _kin * _enddx, - _kin * _enddy ], [0,0]]); + _segments.push([[_endXOut, _endYOut], [ 0,0 ], [ - _kout * _enddx, - _kout * _enddy ]]); + for (var i = 3; i > 0; i--) { + var _rads = i * _span / 4 + _startRads, + _dx = - Math.sin(_rads), + _dy = Math.cos(_rads), + _x = Math.cos(_rads) * _outR, + _y = Math.sin(_rads) * _outR; + _segments.push([[_x, _y], [ _kout * _dx, _kout * _dy], [ - _kout * _dx, - _kout * _dy ]]); + } + _segments.push([[_startXOut, _startYOut], [ _kout * _startdx, _kout * _startdy ], [0, 0]]); + var _path = new paper.Path(); + _path.add.apply(_path, _segments); + _path.fillColor = "#333333"; + _path.opacity = .5; + _path.closed = true; + _path.__representation = _repr; + if (_textX >= -2 && _textX <= 2) { + if (_textY > 0) { + _textY += 6; + } + } + var _text = new paper.PointText(_textX,_textY); + _text.characterStyle = { + fontSize: 9, + fillColor: '#c000c0' + }; + if (_textX > 2) { + _text.paragraphStyle.justification = 'left'; + } else if (_textX < -2) { + _text.paragraphStyle.justification = 'right'; + } else { + _text.paragraphStyle.justification = 'center'; + } + _text.visible = false; + var _visible = false, + _restPos = new paper.Point(-200, -200), + _grp = new paper.Group([_path, _text]), + _delta = _grp.position, + _imgdelta = new paper.Point([_centerX, _centerY]), + _currentPos = new paper.Point(0,0); + _text.content = _caption; + _grp.visible = false; + _grp.position = _restPos; + var _res = { + show: function() { + _visible = true; + _grp.position = _currentPos.add(_delta); + _grp.visible = true; + }, + moveTo: function(_point) { + _currentPos = _point; + if (_visible) { + _grp.position = _point.add(_delta); + } + }, + hide: function() { + _visible = false; + _grp.visible = false; + _grp.position = _restPos; + }, + select: function() { + _path.opacity = .8; + _text.visible = true; + }, + unselect: function() { + _path.opacity = .5; + _text.visible = false; + }, + destroy: function() { + _grp.remove(); + } + } + _img.onload = function() { + var _h = _img.height; + var _raster = new paper.Raster(_img); + _raster.position = _imgdelta.add(_grp.position).subtract(_delta); + _grp.addChild(_raster); + } + _img.src = _imgsrc; + return _res + } +} + +Rkns.Renderer._BaseRepresentation = function(_renderer, _model) { + if (typeof _renderer !== "undefined") { + this.renderer = _renderer; + this.project = _renderer.renkan.project; + this.model = _model; + if (this.model) { + var _this = this; + this._changeBinding = function() { + _this.redraw(); + } + this._removeBinding = function() { + _renderer.removeRepresentation(_this); + _renderer.redraw(); + } + this.model.on("change", this._changeBinding ); + this.model.on("remove", this._removeBinding ); + } + } +} + +Rkns.Renderer._BaseRepresentation.prototype.super = function(_func) { + Rkns.Renderer._BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1)); +} + +Rkns.Renderer._BaseRepresentation.prototype.select = function() {} + +Rkns.Renderer._BaseRepresentation.prototype.unselect = function() {} + +Rkns.Renderer._BaseRepresentation.prototype.highlight = function() {} + +Rkns.Renderer._BaseRepresentation.prototype.unhighlight = function() {} + +Rkns.Renderer._BaseRepresentation.prototype.mouseup = function() {} + +Rkns.Renderer._BaseRepresentation.prototype.destroy = function() { + if (this.model) { + this.model.off("change", this._changeBinding ); + this.model.off("remove", this._removeBinding ); + } +} + +Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.Node.prototype._init = function() { + this.renderer.node_layer.activate(); + this.type = "Node"; + this.circle = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS); + this.circle.fillColor = '#ffffff'; + this.circle.__representation = this; + this.title = new paper.PointText([0,0]); + this.title.characterStyle = { + fontSize: Rkns.Renderer._NODE_FONT_SIZE, + fillColor: 'black' + }; + this.edit_button = new Rkns.Renderer.NodeEditButton(this.renderer, null); + this.edit_button.node_representation = this; + this.remove_button = new Rkns.Renderer.NodeRemoveButton(this.renderer, null); + this.remove_button.node_representation = this; + this.link_button = new Rkns.Renderer.NodeLinkButton(this.renderer, null); + this.link_button.node_representation = this; + this.title.paragraphStyle.justification = 'center'; +} + +Rkns.Renderer.Node.prototype.redraw = function() { + var _model_coords = new paper.Point(this.model.get("position")); + this.paper_coords = this.renderer.toPaperCoords(_model_coords); + this.circle.position = this.paper_coords; + this.title.content = this.model.get("title"); + this.title.position = this.paper_coords.add([0, Rkns.Renderer._NODE_RADIUS + 1.5 *Rkns.Renderer._NODE_FONT_SIZE]); + this.circle.strokeColor = this.model.get("created_by").get("color"); + this.edit_button.moveTo(this.paper_coords); + this.remove_button.moveTo(this.paper_coords); + this.link_button.moveTo(this.paper_coords); + var _img = this.model.get("image"); + if (_img && _img !== this.img) { + var _image = new Image(), + _this = this; + _image.onload = function() { + if (_this.node_image) { + _this.node_image.remove(); + } + _this.renderer.node_layer.activate(); + var _ratio = Math.min(1, 2 * Rkns.Renderer._NODE_RADIUS / _image.width, 2 * Rkns.Renderer._NODE_RADIUS / _image.height ); + var _raster = new paper.Raster(_image); + var _clip = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS); + _raster.scale(_ratio); + _this.node_image = new paper.Group(_clip, _raster); + _this.node_image.opacity = .9; + /* This is a workaround to allow clipping at group level + * If opacity was set to 1, paper.js would merge all clipping groups in one (known bug). + */ + _this.node_image.clipped = true; + _this.node_image.position = _this.paper_coords; + _this.node_image.__representation = _this; + _clip.__representation = _this; + paper.view.draw(); + } + _image.src = _img; + } + this.img = _img; + if (this.node_image) { + if (!this.img) { + this.node_image.remove(); + delete this.node_image; + } else { + this.node_image.position = this.paper_coords; + } + } +} + +Rkns.Renderer.Node.prototype.paperShift = function(_delta) { + var _coords = this.renderer.toModelCoords(this.paper_coords.add(_delta)), + _data = { + position: { + x: _coords.x, + y: _coords.y + } + }; + this.model.set(_data); + this.renderer.redraw(); +} + +Rkns.Renderer.Node.prototype.openEditor = function() { + this.renderer.removeRepresentationsOfType("editor"); + var _editor = this.renderer.addRepresentation("NodeEditor",null); + _editor.node_representation = this; + _editor.draw(); +} + +Rkns.Renderer.Node.prototype.select = function() { + this.circle.strokeWidth = 3; + this.edit_button.show(); + this.remove_button.show(); + this.link_button.show(); + var _uri = this.model.get("uri"); + Rkns.$('.Rk-Bin-Item').each(function() { + var _el = Rkns.$(this); + if (_el.attr("data-uri") == _uri) { + _el.addClass("selected"); + } + }); +} + +Rkns.Renderer.Node.prototype.unselect = function(_newTarget) { + if (!_newTarget || _newTarget.node_representation !== this) { + this.edit_button.hide(); + this.remove_button.hide(); + this.link_button.hide(); + this.circle.strokeWidth = 1; + Rkns.$('.Rk-Bin-Item').removeClass("selected"); + } +} + +Rkns.Renderer.Node.prototype.highlight = function() { + this.circle.fillColor = "#ffff80"; + if (this.node_image) { + this.node_image.opacity = .5; + } +} + +Rkns.Renderer.Node.prototype.unhighlight = function(_newTarget) { + this.circle.fillColor = "#ffffff"; + if (this.node_image) { + this.node_image.opacity = .9; + } +} + +Rkns.Renderer.Node.prototype.mouseup = function(_event) { + if (!this.renderer.is_dragging) { + this.openEditor(); + } + this.renderer.click_target = null; + this.renderer.is_dragging = false; +} + +Rkns.Renderer.Node.prototype.destroy = function(_event) { + this.super("destroy"); + this.edit_button.destroy(); + this.remove_button.destroy(); + this.link_button.destroy(); + this.circle.remove(); + this.title.remove(); + if (this.node_image) { + this.node_image.remove(); + } +} + +/* */ + +Rkns.Renderer.Edge = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.Edge.prototype._init = function() { + this.renderer.edge_layer.activate(); + this.type = "Edge"; + this.from_representation = this.renderer.getRepresentationByModel(this.model.get("from")); + this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to")); + this.bundle = this.renderer.addToBundles(this); + this.line = new paper.Path(); + this.line.add([0,0],[0,0],[0,0]); + this.line.__representation = this; + this.arrow = new paper.Path(); + this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]); + this.arrow.__representation = this; + this.text = new paper.PointText(); + this.text.characterStyle = { + fontSize: Rkns.Renderer._EDGE_FONT_SIZE, + fillColor: 'black' + }; + this.text.paragraphStyle.justification = 'center'; + this.text_angle = 0; + this.arrow_angle = 0; + this.edit_button = new Rkns.Renderer.EdgeEditButton(this.renderer, null); + this.edit_button.edge_representation = this; + this.remove_button = new Rkns.Renderer.EdgeRemoveButton(this.renderer, null); + this.remove_button.edge_representation = this; +} + +Rkns.Renderer.Edge.prototype.redraw = function() { + var _p0a = this.from_representation.paper_coords, + _p1a = this.to_representation.paper_coords, + _v = _p1a.subtract(_p0a), + _r = _v.length, + _u = _v.divide(_r), + _group_pos = this.bundle.getPosition(this), + _delta = new paper.Point([- _u.y, _u.x]).multiply( 12 * _group_pos ), + _p0b = _p0a.add(_delta), /* Adding a 4 px difference */ + _p1b = _p1a.add(_delta), /* to differentiate inbound and outbound links */ + _a = _v.angle, + _handle = _v.divide(3), + _color = this.model.get("created_by").get("color"); + this.paper_coords = _p0b.add(_p1b).divide(2); + this.line.strokeColor = _color; + this.line.segments[0].point = _p0a; + this.line.segments[1].point = this.paper_coords; + this.line.segments[1].handleIn = _handle.multiply(-1); + this.line.segments[1].handleOut = _handle; + this.line.segments[2].point = _p1a; + this.arrow.rotate(_a - this.arrow_angle); + this.arrow.fillColor = _color; + this.arrow.position = this.paper_coords.subtract(_u.multiply(4)); + this.arrow_angle = _a; + if (_a > 90) { + _a -= 180; + } + if (_a < -90) { + _a += 180; + } + this.text.rotate(_a - this.text_angle); + this.text.content = this.model.get("title"); + this.text.position = this.paper_coords; + this.text_angle = _a; + this.edit_button.moveTo(this.paper_coords); + this.remove_button.moveTo(this.paper_coords); +} + +Rkns.Renderer.Edge.prototype.openEditor = function() { + this.renderer.removeRepresentationsOfType("editor"); + var _editor = this.renderer.addRepresentation("EdgeEditor",null); + _editor.edge_representation = this; + _editor.draw(); +} + +Rkns.Renderer.Edge.prototype.select = function() { + this.line.strokeWidth = 3; + this.edit_button.show(); + this.remove_button.show(); +} + +Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) { + if (!_newTarget || _newTarget.edge_representation !== this) { + this.edit_button.hide(); + this.remove_button.hide(); + this.line.strokeWidth = 1; + } +} + +Rkns.Renderer.Edge.prototype.mouseup = function(_event) { + if (!this.renderer.is_dragging) { + this.openEditor(); + } + this.renderer.click_target = null; + this.renderer.is_dragging = false; +} + +Rkns.Renderer.Edge.prototype.paperShift = function(_delta) { + this.from_representation.paperShift(_delta); + this.to_representation.paperShift(_delta); + this.renderer.redraw(); +} + +Rkns.Renderer.Edge.prototype.destroy = function() { + this.super("destroy"); + this.line.remove(); + this.arrow.remove(); + this.text.remove(); + this.edit_button.destroy(); + this.remove_button.destroy(); + var _this = this; + this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) { + return _edge === _this; + }); +} + +/* */ + +Rkns.Renderer.TempEdge = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.TempEdge.prototype._init = function() { + this.renderer.edge_layer.activate(); + this.type = "temp-edge"; + + var _color = this.project.get("users").get(this.renderer.renkan.current_user).get("color"); + this.line = new paper.Path(); + this.line.strokeColor = _color; + this.line.add([0,0],[0,0]); + this.line.__representation = this; + this.arrow = new paper.Path(); + this.arrow.fillColor = _color; + this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]); + this.arrow.__representation = this; + this.arrow_angle = 0; +} + +Rkns.Renderer.TempEdge.prototype.redraw = function() { + var _p0 = this.from_representation.paper_coords, + _p1 = this.end_pos, + _a = _p1.subtract(_p0).angle, + _c = _p0.add(_p1).divide(2); + this.line.segments[0].point = _p0; + this.line.segments[1].point = _p1; + this.arrow.rotate(_a - this.arrow_angle); + this.arrow.position = _c; + this.arrow_angle = _a; +} + +Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) { + this.end_pos = this.end_pos.add(_delta); + var _hitResult = paper.project.hitTest(this.end_pos); + this.renderer.findTarget(_hitResult); + this.redraw(); +} + +Rkns.Renderer.TempEdge.prototype.mouseup = function(_event) { + var _hitResult = paper.project.hitTest(_event.point), + _model = this.from_representation.model, + _endDrag = true; + if (_hitResult && typeof _hitResult.item.__representation !== "undefined") { + var _target = _hitResult.item.__representation; + if (_target.type === "Node" && _model !== _target.model) { + var _data = { + id: Rkns.Utils.getUID('edge'), + created_by: this.renderer.renkan.current_user, + from: _model.get("_id"), + to: _target.model.get("_id") + }; + this.project.addEdge(_data); + } + if (_model === _target.model || (_target.node_representation && _target.node_representation.model === _model)) { + _endDrag = false; + this.renderer.is_dragging = true; + } + } + if (_endDrag) { + this.renderer.click_target = null; + this.renderer.is_dragging = false; + this.renderer.removeRepresentation(this); + paper.view.draw(); + } +} + +Rkns.Renderer.TempEdge.prototype.destroy = function() { + this.arrow.remove(); + this.line.remove(); +} + +/* */ + +Rkns.Renderer.NodeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.NodeEditor.prototype._init = function() { + this.renderer.overlay_layer.activate(); + this.type = "editor"; + this.editor_block = new paper.Path(); + var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]}); + this.editor_block.add.apply(this.editor_block, _pts); + this.editor_block.strokeWidth = 2; + this.editor_block.strokeColor = "#999999"; + this.editor_block.fillColor = "#e0e0e0"; + this.editor_block.opacity = .8; + this.editor_$ = Rkns.$('
') + .appendTo(this.renderer.editor_$) + .css({ + position: "absolute", + opacity: .8 + }) + .hide(); +} + +Rkns.Renderer.NodeEditor.prototype.template = Rkns._.template( + '

×<%=l10n.edit_node%>

' + + '

' + + '

' + + '

' + + '

' + + '

<%=node.created_by_title%>

' +); + +Rkns.Renderer.NodeEditor.prototype.draw = function() { + var _model = this.node_representation.model; + this.editor_$ + .html(this.template({ + node: { + title: _model.get("title"), + uri: _model.get("uri"), + description: _model.get("description"), + image: _model.get("image") || "", + created_by_color: _model.get("created_by").get("color"), + created_by_title: _model.get("created_by").get("title") + }, + l10n: this.renderer.renkan.l10n + })); + this.redraw(); + var _this = this; + this.editor_$.find(".Rk-CloseX").click(function() { + _this.renderer.removeRepresentation(_this); + paper.view.draw(); + }); + this.editor_$.find("input, textarea").bind("keyup change", function() { + var _uri = _this.editor_$.find(".Rk-Edit-URI").val(), + _image = _this.editor_$.find(".Rk-Edit-Image").val(); + _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image); + _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri); + var _data = { + title: _this.editor_$.find(".Rk-Edit-Title").val(), + description: _this.editor_$.find(".Rk-Edit-Description").val(), + uri: _uri, + image: _image + } + _model.set(_data); + _this.redraw(); + }); + this.editor_$.find("img").load(function() { + _this.redraw(); + }) + this.editor_$.find(".Rk-Edit-Title")[0].focus(); +} + +Rkns.Renderer.NodeEditor.prototype.redraw = function() { + var _coords = this.node_representation.paper_coords; + Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 20, this.editor_$); + this.editor_$.show(); + paper.view.draw(); +} + +Rkns.Renderer.NodeEditor.prototype.destroy = function() { + this.editor_block.remove(); + this.editor_$.detach(); +} + +/* */ + +Rkns.Renderer.EdgeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.EdgeEditor.prototype._init = function() { + this.renderer.overlay_layer.activate(); + this.type = "editor"; + this.editor_block = new paper.Path(); + var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]}); + this.editor_block.add.apply(this.editor_block, _pts); + this.editor_block.strokeWidth = 2; + this.editor_block.strokeColor = "#999999"; + this.editor_block.fillColor = "#e0e0e0"; + this.editor_block.opacity = .8; + this.editor_$ = Rkns.$('
') + .appendTo(this.renderer.editor_$) + .css({ + position: "absolute", + opacity: .8 + }) + .hide(); +} + +Rkns.Renderer.EdgeEditor.prototype.template = Rkns._.template( + '

×<%=l10n.edit_edge%>

' + + '

' + + '

' + + '

<%=edge.from_title%>

' + + '

<%=edge.to_title%>

' + + '

<%=edge.created_by_title%>

' +); + +Rkns.Renderer.EdgeEditor.prototype.draw = function() { + var _model = this.edge_representation.model; + this.editor_$ + .html(this.template({ + edge: { + title: _model.get("title"), + uri: _model.get("uri"), + description: _model.get("description"), + from_title: _model.get("from").get("title"), + to_title: _model.get("to").get("title"), + from_created_by_color: _model.get("from").get("created_by").get("color"), + to_created_by_color: _model.get("to").get("created_by").get("color"), + created_by_color: _model.get("created_by").get("color"), + created_by_title: _model.get("created_by").get("title") + }, + l10n: this.renderer.renkan.l10n + })); + this.redraw(); + var _this = this; + this.editor_$.find(".Rk-CloseX").click(function() { + _this.renderer.removeRepresentation(_this); + paper.view.draw(); + }); + this.editor_$.find("input, textarea").bind("keyup change", function() { + _this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val()); + var _data = { + title: _this.editor_$.find(".Rk-Edit-Title").val(), + uri: _this.editor_$.find(".Rk-Edit-URI").val() + } + _model.set(_data); + _this.redraw(); + }); +} +Rkns.Renderer.EdgeEditor.prototype.redraw = function() { + var _coords = this.edge_representation.paper_coords; + Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 5, this.editor_$); + this.editor_$.show(); + paper.view.draw(); +} + +Rkns.Renderer.EdgeEditor.prototype.destroy = function() { + this.editor_block.remove(); + this.editor_$.detach(); +} + +/* */ + +Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.NodeEditButton.prototype._init = function() { + this.renderer.overlay_layer.activate(); + this.type = "Node-edit-button"; + this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, - 90, 30, 1, this.renderer.renkan.static_url+'img/edit.png', this.renderer.renkan.l10n.caption_edit); +} + +Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) { + this.sector.moveTo(_pos); +} + +Rkns.Renderer.NodeEditButton.prototype.show = function() { + this.sector.show(); +} + +Rkns.Renderer.NodeEditButton.prototype.hide = function() { + this.sector.hide(); +} + +Rkns.Renderer.NodeEditButton.prototype.select = function() { + this.sector.select(); +} + +Rkns.Renderer.NodeEditButton.prototype.unselect = function(_newTarget) { + this.sector.unselect(); + if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) { + this.node_representation.unselect(); + } +} + +Rkns.Renderer.NodeEditButton.prototype.mouseup = function() { + if (!this.renderer.is_dragging) { + this.node_representation.openEditor(); + } +} + +Rkns.Renderer.NodeEditButton.prototype.destroy = function() { + this.sector.destroy(); +} + +/* */ + +Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.NodeRemoveButton.prototype._init = function() { + this.renderer.overlay_layer.activate(); + this.type = "Node-remove-button"; + this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, -210, -90, 1, this.renderer.renkan.static_url+'img/remove.png', this.renderer.renkan.l10n.caption_remove); +} + +Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) { + this.sector.moveTo(_pos); +} + +Rkns.Renderer.NodeRemoveButton.prototype.show = function() { + this.sector.show(); +} + +Rkns.Renderer.NodeRemoveButton.prototype.hide = function() { + this.sector.hide(); +} + +Rkns.Renderer.NodeRemoveButton.prototype.select = function() { + this.sector.select(); +} + +Rkns.Renderer.NodeRemoveButton.prototype.unselect = function(_newTarget) { + this.sector.unselect(); + if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) { + this.node_representation.unselect(); + } +} + +Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() { + this.renderer.removeRepresentationsOfType("editor"); + if (confirm('Do you really wish to remove node "' + this.node_representation.model.get("title") + '"?')) { + this.project.removeNode(this.node_representation.model); + } +} + +Rkns.Renderer.NodeRemoveButton.prototype.destroy = function() { + this.sector.destroy(); +} + +/* */ + +Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.NodeLinkButton.prototype._init = function() { + this.renderer.overlay_layer.activate(); + this.type = "Node-link-button"; + this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._NODE_BUTTON_INNER, Rkns.Renderer._NODE_BUTTON_OUTER, 30, 150, 1, this.renderer.renkan.static_url+'img/link.png', this.renderer.renkan.l10n.caption_link); +} + +Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) { + this.sector.moveTo(_pos); +} + +Rkns.Renderer.NodeLinkButton.prototype.show = function() { + this.sector.show(); +} + +Rkns.Renderer.NodeLinkButton.prototype.hide = function() { + this.sector.hide(); +} + +Rkns.Renderer.NodeLinkButton.prototype.select = function() { + this.sector.select(); +} + +Rkns.Renderer.NodeLinkButton.prototype.unselect = function(_newTarget) { + this.sector.unselect(); + if (!_newTarget || (_newTarget !== this.node_representation && _newTarget.node_representation !== this.node_representation)) { + this.node_representation.unselect(); + } +} + +Rkns.Renderer.NodeLinkButton.prototype.destroy = function() { + this.sector.destroy(); +} + +/* */ + +Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.EdgeEditButton.prototype._init = function() { + this.renderer.overlay_layer.activate(); + this.type = "Edge-edit-button"; + 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.l10n.caption_edit); +} + +Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) { + this.sector.moveTo(_pos); +} + +Rkns.Renderer.EdgeEditButton.prototype.show = function() { + this.sector.show(); +} + +Rkns.Renderer.EdgeEditButton.prototype.hide = function() { + this.sector.hide(); +} + +Rkns.Renderer.EdgeEditButton.prototype.select = function() { + this.sector.select(); +} + +Rkns.Renderer.EdgeEditButton.prototype.unselect = function(_newTarget) { + this.sector.unselect(); + if (!_newTarget || (_newTarget !== this.edge_representation && _newTarget.edge_representation !== this.edge_representation)) { + this.edge_representation.unselect(); + } +} + +Rkns.Renderer.EdgeEditButton.prototype.mouseup = function() { + if (!this.renderer.is_dragging) { + this.edge_representation.openEditor(); + } +} + +Rkns.Renderer.EdgeEditButton.prototype.destroy = function() { + this.sector.destroy(); +} + +/* */ + +Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.EdgeRemoveButton.prototype._init = function() { + this.renderer.overlay_layer.activate(); + this.type = "Edge-remove-button"; + 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.l10n.caption_remove); +} +Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) { + this.sector.moveTo(_pos); +} + +Rkns.Renderer.EdgeRemoveButton.prototype.show = function() { + this.sector.show(); +} + +Rkns.Renderer.EdgeRemoveButton.prototype.hide = function() { + this.sector.hide(); +} + +Rkns.Renderer.EdgeRemoveButton.prototype.select = function() { + this.sector.select(); +} + +Rkns.Renderer.EdgeRemoveButton.prototype.unselect = function(_newTarget) { + this.sector.unselect(); + if (!_newTarget || (_newTarget !== this.edge_representation && _newTarget.edge_representation !== this.edge_representation)) { + this.edge_representation.unselect(); + } +} + +Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() { + this.renderer.removeRepresentationsOfType("editor"); + if (confirm('Do you really wish to remove edge "' + this.edge_representation.model.get("title") + '"?')) { + this.project.removeEdge(this.edge_representation.model); + } +} + +Rkns.Renderer.EdgeRemoveButton.prototype.destroy = function() { + this.sector.destroy(); +} + +/* */ + +Rkns.Renderer.Scene = function(_renkan) { + this.renkan = _renkan; + this.$ = Rkns.$(".Rk-Render"); + this.representations = []; + this.$.html(this.template({ + l10n: _renkan.l10n + })) + this.canvas_$ = this.$.find(".Rk-Canvas"); + this.editor_$ = this.$.find(".Rk-Editor"); + this.notif_$ = this.$.find(".Rk-Notifications"); + paper.setup(this.canvas_$[0]); + this.scale = 1; + this.offset = paper.view.center; + this.totalScroll = 0; + this.click_target = null; + this.selected_target = null; + this.edge_layer = new paper.Layer(); + this.node_layer = new paper.Layer(); + this.overlay_layer = new paper.Layer(); + this.bundles = []; + this.click_mode = false; + var _tool = new paper.Tool(), + _this = this; + _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE; + _tool.onMouseMove = function(_event) { + _this.onMouseMove(_event); + } + _tool.onMouseDown = function(_event) { + _this.onMouseDown(_event); + } + _tool.onMouseDrag = function(_event) { + _this.onMouseDrag(_event); + } + this.canvas_$.mouseup(function(_event) { + _this.onMouseUp(_event); + }); + this.canvas_$.mousewheel(function(_event, _delta) { + _this.onScroll(_event, _delta); + }); + this.canvas_$.dblclick(function(_event) { + _this.onDoubleClick(_event); + }); + this.canvas_$.mouseenter(function(_event) { + _this.onMouseEnter(_event); + }); + this.editor_$.find(".Rk-ZoomOut").click(function() { + _this.offset = new paper.Point([ + _this.canvas_$.width(), + _this.canvas_$.height() + ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 )); + _this.setScale( _this.scale * Math.SQRT1_2 ); + _this.redraw(); + }); + this.editor_$.find(".Rk-ZoomIn").click(function() { + _this.offset = new paper.Point([ + _this.canvas_$.width(), + _this.canvas_$.height() + ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 )); + _this.setScale( _this.scale * Math.SQRT2 ); + _this.redraw(); + }); + this.$.find(".Rk-CurrentUser").mouseenter( + function() { _this.$.find(".Rk-UserList").slideDown() } + ); + this.$.find(".Rk-Users").mouseleave( + function() { _this.$.find(".Rk-UserList").slideUp(); } + ); + this.$.find(".Rk-FullScreen-Button").click(function() { + var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen, + _el = _this.renkan.$[0], + _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"], + _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"]; + if (_isFull) { + for (var i = 0; i < _cancelMethods.length; i++) { + if (typeof document[_cancelMethods[i]] === "function") { + document[_cancelMethods[i]](); + break; + } + } + } else { + for (var i = 0; i < _requestMethods.length; i++) { + if (typeof _el[_requestMethods[i]] === "function") { + _el[_requestMethods[i]](); + break; + } + } + } + }); + this.$.find(".Rk-AddNode-Button").click(function() { + if (_this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) { + _this.click_mode = false; + _this.notif_$.hide(); + } else { + _this.click_mode = Rkns.Renderer._CLICKMODE_ADDNODE; + _this.notif_$.html(_renkan.l10n.notif_add_node).fadeIn(); + } + }); + this.$.find(".Rk-AddEdge-Button").click(function() { + if (_this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE || _this.click_mode === Rkns.Renderer._CLICKMODE_ENDEDGE) { + _this.click_mode = false; + _this.notif_$.hide(); + } else { + _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE; + _this.notif_$.html(_renkan.l10n.notif_start_edge).fadeIn(); + } + }); + this.$.find(".Rk-TopBar-Button").mouseover(function() { + Rkns.$(this).find(".Rk-TopBar-Tooltip").show(); + }).mouseout(function() { + Rkns.$(this).find(".Rk-TopBar-Tooltip").hide(); + }); + + paper.view.onResize = function(_event) { + _this.offset = _this.offset.add(_event.delta.divide(2)); + _this.redraw(); + } + + var _thRedraw = Rkns._.throttle(function() { + _this.redraw(); + },50); + + this.addRepresentations("Node", this.renkan.project.get("nodes")); + this.addRepresentations("Edge", this.renkan.project.get("edges")); + this.renkan.project.get("users").each(function(_user) { + _this.addUser(_user); + }) + + this.renkan.project.on("add:users", function(_user) { + _this.addUser(_user); + }); + this.renkan.project.on("add:nodes", function(_node) { + _this.addRepresentation("Node", _node); + _thRedraw(); + }); + this.renkan.project.on("add:edges", function(_edge) { + _this.addRepresentation("Edge", _edge); + _thRedraw(); + }); + + this.redraw(); +} + +Rkns.Renderer.Scene.prototype.template = Rkns._.template( + '

<%=l10n.untitled_project%>

' + + '
<unknown user>
    ' + + '
    <%=l10n.full_screen%>
    ' + + '
    <%=l10n.add_node%>
    ' + + '
    <%=l10n.add_edge%>
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' +); + +Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) { + var _bundle = Rkns._(this.bundles).find(function(_bundle) { + return ( + ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation ) + || ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation ) + ); + }); + if (typeof _bundle !== "undefined") { + _bundle.edges.push(_edgeRepr) + } else { + _bundle = { + from: _edgeRepr.from_representation, + to: _edgeRepr.to_representation, + edges: [ _edgeRepr ], + getPosition: function(_er) { + var _dir = (_er.from_representation === this.from) ? 1 : -1; + return _dir * ( Rkns._(this.edges).indexOf(_er) - (this.edges.length - 1) / 2 ); + } + } + this.bundles.push(_bundle); + } + return _bundle; +} + +Rkns.Renderer.Scene.prototype.setScale = function(_newScale) { + this.scale = _newScale; + this.redraw(); +} + +Rkns.Renderer.Scene.prototype.autoScale = function() { + var nodes = this.renkan.project.get("nodes") + if (nodes.length > 1) { + var _xx = nodes.map(function(_node) { return _node.get("position").x }), + _yy = nodes.map(function(_node) { return _node.get("position").y }), + _minx = Math.min.apply(Math, _xx), + _miny = Math.min.apply(Math, _yy), + _maxx = Math.max.apply(Math, _xx), + _maxy = Math.max.apply(Math, _yy); + var _scale = Math.min((paper.view.size.width - 2 * Rkns.Renderer._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * Rkns.Renderer._MARGIN_Y) / (_maxy - _miny)); + this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)); + this.setScale(_scale); + } + if (nodes.length === 1) { + this.offset = paper.view.center.subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y])); + this.setScale(1); + } +} + +Rkns.Renderer.Scene.prototype.toPaperCoords = function(_point) { + return _point.multiply(this.scale).add(this.offset); +} + + +Rkns.Renderer.Scene.prototype.toModelCoords = function(_point) { + return _point.subtract(this.offset).divide(this.scale); +} + +Rkns.Renderer.Scene.prototype.addRepresentation = function(_type, _model) { + var _repr = new Rkns.Renderer[_type](this, _model); + this.representations.push(_repr); + return _repr; +} + +Rkns.Renderer.Scene.prototype.addRepresentations = function(_type, _collection) { + var _this = this; + _collection.forEach(function(_model) { + _this.addRepresentation(_type, _model); + }); +} + +Rkns.Renderer.Scene.prototype.userTemplate = Rkns._.template( + '
  • <%=name%>
  • ' +); + +Rkns.Renderer.Scene.prototype.addUser = function(_user) { + if (_user.get("_id") === this.renkan.current_user) { + this.$.find(".Rk-CurrentUser-Name").text(_user.get("title")); + this.$.find(".Rk-CurrentUser-Color").css("background", _user.get("color")); + } else { + this.$.find(".Rk-UserList").append( + Rkns.$( + this.userTemplate({ + name: _user.get("title"), + background: _user.get("color") + }) + ) + ); + } +} + +Rkns.Renderer.Scene.prototype.removeRepresentation = function(_representation) { + _representation.destroy(); + this.representations = Rkns._(this.representations).reject( + function(_repr) { + return _repr == _representation + } + ); +} + +Rkns.Renderer.Scene.prototype.getRepresentationByModel = function(_model) { + return Rkns._(this.representations).find(function(_repr) { + return _repr.model === _model; + }); +} + +Rkns.Renderer.Scene.prototype.removeRepresentationsOfType = function(_type) { + var _representations = Rkns._(this.representations).filter(function(_repr) { + return _repr.type == _type; + }), + _this = this; + Rkns._(_representations).each(function(_repr) { + _this.removeRepresentation(_repr); + }); +} + +Rkns.Renderer.Scene.prototype.highlightModel = function(_model) { + var _repr = this.getRepresentationByModel(_model); + if (_repr) { + _repr.highlight(); + } +} + +Rkns.Renderer.Scene.prototype.unhighlightAll = function(_model) { + Rkns._(this.representations).each(function(_repr) { + _repr.unhighlight(); + }); +} + +Rkns.Renderer.Scene.prototype.redraw = function() { + Rkns._(this.representations).each(function(_representation) { + _representation.redraw(); + }); + paper.view.draw(); +} + +Rkns.Renderer.Scene.prototype.addTempEdge = function(_from, _point) { + var _tmpEdge = this.addRepresentation("TempEdge",null); + _tmpEdge.end_pos = _point; + _tmpEdge.from_representation = _from; + _tmpEdge.redraw(); + this.click_target = _tmpEdge; +} + +Rkns.Renderer.Scene.prototype.findTarget = function(_hitResult) { + if (_hitResult && typeof _hitResult.item.__representation !== "undefined") { + var _newTarget = _hitResult.item.__representation; + if (this.selected_target !== _hitResult.item.__representation) { + if (this.selected_target) { + this.selected_target.unselect(_newTarget); + } + _newTarget.select(this.selected_target); + this.selected_target = _newTarget; + } + } else { + if (this.selected_target) { + this.selected_target.unselect(null); + } + this.selected_target = null; + } +} + +Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) { + var _hitResult = paper.project.hitTest(_event.point); + if (this.is_dragging) { + if (this.click_target && typeof this.click_target.paperShift === "function") { + this.click_target.paperShift(_event.delta); + } else { + this.offset = this.offset.add(_event.delta); + this.redraw(); + } + } else { + this.findTarget(_hitResult); + } +} + +Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) { + if (!this.click_target || this.click_target.type !== "temp-edge") { + this.is_dragging = false; + var _hitResult = paper.project.hitTest(_event.point); + if (_hitResult && typeof _hitResult.item.__representation !== "undefined") { + this.click_target = _hitResult.item.__representation; + if (this.click_target.type === "Node-link-button") { + this.removeRepresentationsOfType("editor"); + this.addTempEdge(this.click_target.node_representation, _event.point); + } + } else { + this.click_target = null; + if (this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) { + var _coords = this.toModelCoords(_event.point), + _data = { + id: Rkns.Utils.getUID('node'), + created_by: this.renkan.current_user, + position: { + x: _coords.x, + y: _coords.y + } + }; + _node = this.renkan.project.addNode(_data); + this.getRepresentationByModel(_node).openEditor(); + } + } + } + if (this.click_mode) { + if (this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === "Node") { + this.removeRepresentationsOfType("editor"); + this.addTempEdge(this.click_target, _event.point); + this.click_mode = Rkns.Renderer._CLICKMODE_ENDEDGE; + this.notif_$.fadeOut(function() { + Rkns.$(this).html(_renkan.l10n.notif_end_edge).fadeIn(); + }); + } else { + this.notif_$.hide(); + this.click_mode = false; + } + } +} + +Rkns.Renderer.Scene.prototype.onMouseDrag = function(_event) { + this.is_dragging = true; + this.onMouseMove(_event); +} + +Rkns.Renderer.Scene.prototype.onMouseUp = function(_event) { + if (this.click_target) { + var _off = this.canvas_$.offset(); + this.click_target.mouseup( + { + point: new paper.Point([ + _event.pageX - _off.left, + _event.pageY - _off.top + ]) + } + ); + } else { + this.click_target = null; + this.is_dragging = false; + } +} + +Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) { + this.totalScroll += _scrolldelta; + if (Math.abs(this.totalScroll) >= 1) { + var _off = this.canvas_$.offset(), + _delta = new paper.Point([ + _event.pageX - _off.left, + _event.pageY - _off.top + ]).subtract(this.offset).multiply( Math.SQRT2 - 1 ); + if (this.totalScroll > 0) { + this.offset = this.offset.subtract(_delta); + this.setScale( this.scale * Math.SQRT2 ); + } else { + this.offset = this.offset.add(_delta.divide( Math.SQRT2 )); + this.setScale( this.scale * Math.SQRT1_2); + } + this.totalScroll = 0; + this.redraw(); + } +} + +Rkns.Renderer.Scene.prototype.onDoubleClick = function(_event) { + var _off = this.canvas_$.offset(), + _point = new paper.Point([ + _event.pageX - _off.left, + _event.pageY - _off.top + ]); + var _hitResult = paper.project.hitTest(_point); + if (!_hitResult || typeof _hitResult.item.__representation === "undefined") { + var _coords = this.toModelCoords(_point), + _data = { + id: Rkns.Utils.getUID('node'), + created_by: this.renkan.current_user, + position: { + x: _coords.x, + y: _coords.y + } + }; + _node = this.renkan.project.addNode(_data); + this.getRepresentationByModel(_node).openEditor(); + } + paper.view.draw(); +} + +Rkns.Renderer.Scene.prototype.onMouseEnter = function(_event) { + var _newEl = this.renkan.selected_bin_item; + if (_newEl) { + var _off = this.canvas_$.offset(), + _point = new paper.Point([ + _event.pageX - _off.left, + _event.pageY - _off.top + ]), + _coords = this.toModelCoords(_point), + _data = { + id: Rkns.Utils.getUID('node'), + created_by: this.renkan.current_user, + uri: _newEl.uri, + title: _newEl.title, + description: _newEl.description, + image: _newEl.image, + position: { + x: _coords.x, + y: _coords.y + } + }; + var _node = this.renkan.project.addNode(_data); + this.renkan.selected_bin_item = null; + this.is_dragging = true; + this.click_target = this.getRepresentationByModel(_node); + } +} \ No newline at end of file