diff -r f5297dde9053 -r 67085e6281e5 client/js/paper-renderer.js --- a/client/js/paper-renderer.js Fri Jul 27 19:15:32 2012 +0200 +++ b/client/js/paper-renderer.js Mon Jul 30 17:52:13 2012 +0200 @@ -1,11 +1,56 @@ Rkns.Renderers.Paper = Rkns.Utils.inherit(Rkns.Renderers._Base); +Rkns.Renderers.Paper__Utils = { + _EDITOR_ARROW_LENGTH : 20, + _EDITOR_ARROW_WIDTH : 40, + _EDITOR_MARGIN : 15, + _EDITOR_PADDING : 10, + drawEditBox : function(_coords, _path, _width, _height) { + var _isLeft = (_coords.x < paper.view.center.x ? 1 : -1), + _left = _coords.x + _isLeft * ( this._EDITOR_MARGIN + this._EDITOR_ARROW_LENGTH ), + _right = _coords.x + _isLeft * ( this._EDITOR_MARGIN + this._EDITOR_ARROW_LENGTH + _width ), + _top = _coords.y - _height / 2; + if (_top < this._EDITOR_MARGIN) { + _top = Math.min( this._EDITOR_MARGIN, _coords.y - this._EDITOR_ARROW_WIDTH / 2 ); + } + var _bottom = _top + _height; + if (_bottom > (paper.view.size.height - this._EDITOR_MARGIN)) { + _bottom = Math.max( paper.view.size.height - this._EDITOR_MARGIN, _coords.y + this._EDITOR_ARROW_WIDTH / 2 ); + _top = _bottom - _height; + } + _path.segments[0].point + = _path.segments[7].point + = _coords.add([_isLeft * this._EDITOR_MARGIN, 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 - this._EDITOR_ARROW_WIDTH / 2; + _path.segments[6].point.y = _coords.y + this._EDITOR_ARROW_WIDTH / 2; + return { + left: (this._EDITOR_PADDING + Math.min(_left, _right)), + top: (this._EDITOR_PADDING + _top) + } + } +} + Rkns.Renderers.Paper__Controllers = {} Rkns.Renderers.Paper__Controllers._Base = function(_renderer, _element) { if (typeof _renderer !== "undefined") { this.id = Rkns.Utils.getUID('controller'); this._renderer = _renderer; + this._project = _renderer._project; this._element = _element; this._element.__controller = this; } @@ -15,6 +60,8 @@ Rkns.Renderers.Paper__Controllers._Base.prototype.unselect = function() {} +Rkns.Renderers.Paper__Controllers._Base.prototype.destroy = function() {} + Rkns.Renderers.Paper__Controllers.Node = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base); Rkns.Renderers.Paper__Controllers.Node.prototype._init = function() { @@ -42,8 +89,14 @@ } Rkns.Renderers.Paper__Controllers.Node.prototype.paperShift = function(_delta) { - this._element.setPosition(this._renderer.toModelCoords(this.node_paper_coords.add(_delta))); - this._renderer._project.serializer.save(); + var _coords = this._renderer.toModelCoords(this.node_paper_coords.add(_delta)), + _data = { + position: { + x: _coords.x, + y: _coords.y + } + }; + this._project.updateElement(this._element, _data, Rkns._SAVE); this._renderer.redraw(); } @@ -85,14 +138,14 @@ var _p0 = this.from_node_controller.node_paper_coords, _p1 = this.to_node_controller.node_paper_coords, _a = _p1.subtract(_p0).angle, - _center = _p0.add(_p1).divide(2), _color = this._element.created_by.color; + this.edge_paper_coords = _p0.add(_p1).divide(2); this.edge_line.strokeColor = _color; this.edge_line.segments[0].point = _p0; this.edge_line.segments[1].point = _p1; this.edge_arrow.rotate(_a - this.edge_arrow_angle); this.edge_arrow.fillColor = _color; - this.edge_arrow.position = _center; + this.edge_arrow.position = this.edge_paper_coords; this.edge_arrow_angle = _a; if (_a > 90) { _a -= 180; @@ -102,7 +155,7 @@ } this.edge_text.rotate(_a - this.edge_text_angle); this.edge_text.content = this._element.title; - this.edge_text.position = _center; + this.edge_text.position = this.edge_paper_coords; this.edge_text_angle = _a; } @@ -119,6 +172,7 @@ this.to_node_controller.paperShift(_delta); this._renderer.redraw(); } + /* */ Rkns.Renderers.Paper__Controllers.TempEdge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base); @@ -126,7 +180,7 @@ Rkns.Renderers.Paper__Controllers.TempEdge.prototype._init = function() { this._renderer.edge_layer.activate(); this.type = "temp-edge"; - var _color = this._renderer._project.current_user.color; + var _color = this._project.current_user.color; this.edge_line = new paper.Path(); this.edge_line.strokeColor = _color; this.edge_line.add([0,0],[0,0]); @@ -161,15 +215,155 @@ if (_hitResult && typeof _hitResult.item.__controller !== "undefined") { var _target = _hitResult.item.__controller; if (_target.type === "node" && this.from_node_controller._element.id !== _target._element.id) { - this._renderer._project.addEdge({ + this._project.addEdge({ from: this.from_node_controller._element.id, to: _target._element.id }, Rkns._RENDER_AND_SAVE) } } + this._renderer.removeController(this); +} + +Rkns.Renderers.Paper__Controllers.TempEdge.prototype.destroy = function() { this.edge_arrow.remove(); this.edge_line.remove(); - this._renderer.controllers.removeId(this.id); +} + +/* */ + +Rkns.Renderers.Paper__Controllers.NodeEditor = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base); + +Rkns.Renderers.Paper__Controllers.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('.Rk-Editor') + .css({ + position: "absolute", + opacity: .8 + }) + .hide(); +} + +Rkns.Renderers.Paper__Controllers.NodeEditor.prototype.template = Rkns._.template( + '

×<%=l10n.edit_node%>

' + + '

' + + '

' + + '

' + + '

<%=node.created_by.title%>

' +); + +Rkns.Renderers.Paper__Controllers.NodeEditor.prototype.redraw = function() { + var _coords = this.node_controller.node_paper_coords, + _element = this.node_controller._element, + _css = Rkns.Renderers.Paper__Utils.drawEditBox(_coords, this.editor_block, 250, 300); + this.editor_$ + .html(this.template({ + node: _element, + l10n: this._project.l10n + })) + .show() + .css(_css); + var _this = this; + this.editor_$.find(".Rk-CloseX").click(function() { + _this._renderer.removeController(_this); + paper.view.draw(); + }); + this.editor_$.find("input, textarea").bind("keyup change", function() { + var _data = { + title: _this.editor_$.find(".Rk-Edit-Title").val(), + description: _this.editor_$.find(".Rk-Edit-Description").val(), + uri: _this.editor_$.find(".Rk-Edit-URI").val() + } + _this._project.updateElement( + _element, + _data, + Rkns._SAVE + ); + _this.node_controller.redraw(); + paper.view.draw(); + }); +} + +Rkns.Renderers.Paper__Controllers.NodeEditor.prototype.destroy = function() { + this.editor_block.remove(); + this.editor_$.detach(); +} + + +/* */ + +Rkns.Renderers.Paper__Controllers.EdgeEditor = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base); + +Rkns.Renderers.Paper__Controllers.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('.Rk-Editor') + .css({ + position: "absolute", + opacity: .8 + }) + .hide(); +} + +Rkns.Renderers.Paper__Controllers.EdgeEditor.prototype.template = Rkns._.template( + '

×<%=l10n.edit_edge%>

' + + '

' + + '

' + + '

<%=edge.from.title%>

' + + '

<%=edge.to.title%>

' + + '

<%=edge.created_by.title%>

' +); + +Rkns.Renderers.Paper__Controllers.EdgeEditor.prototype.redraw = function() { + var _coords = this.edge_controller.edge_paper_coords, + _element = this.edge_controller._element, + _css = Rkns.Renderers.Paper__Utils.drawEditBox(_coords, this.editor_block, 250, 200); + this.editor_$ + .html(this.template({ + edge: _element, + l10n: this._project.l10n + })) + .show() + .css(_css); + var _this = this; + this.editor_$.find(".Rk-CloseX").click(function() { + _this._renderer.removeController(_this); + paper.view.draw(); + }); + this.editor_$.find("input, textarea").bind("keyup change", function() { + var _data = { + title: _this.editor_$.find(".Rk-Edit-Title").val(), + uri: _this.editor_$.find(".Rk-Edit-URI").val() + } + _this._project.updateElement( + _element, + _data, + Rkns._SAVE + ); + _this.edge_controller.redraw(); + paper.view.draw(); + }); +} + +Rkns.Renderers.Paper__Controllers.EdgeEditor.prototype.destroy = function() { + this.editor_block.remove(); + this.editor_$.detach(); } /* */ @@ -183,12 +377,14 @@ this.scale = 1; this.offset = paper.view.center; this.totalScroll = 0; - this.dragging_target = null; + 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(); var _tool = new paper.Tool(), _this = this; + _tool.minDistance = Rkns._MIN_DRAG_DISTANCE; _tool.onMouseMove = function(_event) { _this.onMouseMove(_event); } @@ -234,21 +430,36 @@ this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(this.scale)); this.controllers = new Rkns.Model.List(); this._project.nodes.forEach(function(_node) { - _this.addElement("Node", _node); + _this.addController("Node", _node); }); this._project.edges.forEach(function(_edge) { - _this.addElement("Edge", _edge); + _this.addController("Edge", _edge); }); this.redraw(); } -Rkns.Renderers.Paper.prototype.addElement = function(_type, _element) { - var _el = new Rkns.Renderers.Paper__Controllers[_type](this, _element); +Rkns.Renderers.Paper.prototype.addController = function(_type, _controller) { + var _el = new Rkns.Renderers.Paper__Controllers[_type](this, _controller); this.controllers.push(_el); return _el; } +Rkns.Renderers.Paper.prototype.removeController = function(_controller) { + _controller.destroy(); + this.controllers.removeId(_controller); +} + +Rkns.Renderers.Paper.prototype.removeControllersOfType = function(_type) { + var _controllers = this.controllers.filter(function(_ctrl) { + return _ctrl.type == _type; + }), + _this = this; + _controllers.forEach(function(_ctrl) { + _this.removeController(_ctrl); + }); +} + Rkns.Renderers.Paper.prototype.redraw = function() { this.controllers.forEach(function(_controller) { _controller.redraw(); @@ -275,24 +486,26 @@ } Rkns.Renderers.Paper.prototype.onMouseDown = function(_event) { + this.is_dragging = false; var _hitResult = paper.project.hitTest(_event.point); if (_hitResult && typeof _hitResult.item.__controller !== "undefined") { - this.dragging_target = _hitResult.item.__controller; - if (this.dragging_target.type === "node" && _hitResult.type === "stroke") { - var _tmpEdge = this.addElement("TempEdge",{}); + this.click_target = _hitResult.item.__controller; + if (this.click_target.type === "node" && _hitResult.type === "stroke") { + var _tmpEdge = this.addController("TempEdge",{}); _tmpEdge.end_pos = _event.point; - _tmpEdge.from_node_controller = this.dragging_target; + _tmpEdge.from_node_controller = this.click_target; _tmpEdge.redraw(); - this.dragging_target = _tmpEdge; + this.click_target = _tmpEdge; } } else { - this.dragging_target = null; + this.click_target = null; } } Rkns.Renderers.Paper.prototype.onMouseDrag = function(_event) { - if (this.dragging_target && typeof this.dragging_target.paperShift === "function") { - this.dragging_target.paperShift(_event.delta); + this.is_dragging = true; + 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(); @@ -300,10 +513,31 @@ } Rkns.Renderers.Paper.prototype.onMouseUp = function(_event) { - if (this.dragging_target && this.dragging_target.type === "temp-edge") { - this.dragging_target.finishEdge(_event); + if (this.click_target) { + switch (this.click_target.type) { + case "node": + if (!this.is_dragging) { + this.removeControllersOfType("editor"); + var _editor = this.addController("NodeEditor",{}); + _editor.node_controller = this.click_target; + _editor.redraw(); + } + break; + case "edge": + if (!this.is_dragging) { + this.removeControllersOfType("editor"); + var _editor = this.addController("EdgeEditor",{}); + _editor.edge_controller = this.click_target; + _editor.redraw(); + } + break; + case "temp-edge": + this.click_target.finishEdge(_event); + break; + } } - this.dragging_target = null; + this.is_dragging = false; + this.click_target = null; } Rkns.Renderers.Paper.prototype.onScroll = function(_event, _scrolldelta) {