client/js/paper-renderer.js
changeset 4 f5297dde9053
parent 3 7722ec70c01b
child 5 67085e6281e5
--- a/client/js/paper-renderer.js	Fri Jul 27 12:22:10 2012 +0200
+++ b/client/js/paper-renderer.js	Fri Jul 27 19:15:32 2012 +0200
@@ -4,28 +4,32 @@
 
 Rkns.Renderers.Paper__Controllers._Base = function(_renderer, _element) {
     if (typeof _renderer !== "undefined") {
+        this.id = Rkns.Utils.getUID('controller');
         this._renderer = _renderer;
         this._element = _element;
         this._element.__controller = this;
     }
 }
 
+Rkns.Renderers.Paper__Controllers._Base.prototype.select = function() {}
+
+Rkns.Renderers.Paper__Controllers._Base.prototype.unselect = function() {}
+
 Rkns.Renderers.Paper__Controllers.Node = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
 
 Rkns.Renderers.Paper__Controllers.Node.prototype._init = function() {
     this._renderer.node_layer.activate();
     this.type = "node";
-    this.node_circle = new paper.Path.Circle([0, 0], 20);
+    this.node_circle = new paper.Path.Circle([0, 0], Rkns._NODE_RADIUS);
     this.node_circle.fillColor = '#ffffff';
     this.node_circle.__controller = this;
     this.node_text = new paper.PointText([0,0]);
     this.node_text.characterStyle = {
-        fontSize: 14,
+        fontSize: Rkns._NODE_FONT_SIZE,
         fillColor: 'black'
     };
     this.node_text.paragraphStyle.justification = 'center';
     this.node_text.__controller = this;
-    this.redraw();
 }
 
 Rkns.Renderers.Paper__Controllers.Node.prototype.redraw = function() {
@@ -33,20 +37,28 @@
     this.node_paper_coords = this._renderer.toPaperCoords(this.node_model_coords);
     this.node_circle.position = this.node_paper_coords;
     this.node_text.content = this._element.title;
-    this.node_text.position = this.node_paper_coords.add([0, 35]);
+    this.node_text.position = this.node_paper_coords.add([0, 2 * Rkns._NODE_RADIUS]);
     this.node_circle.strokeColor = this._element.created_by.color;
 }
 
 Rkns.Renderers.Paper__Controllers.Node.prototype.paperShift = function(_delta) {
-    this._element.setPosition(Rkns._FROM_GRAPHICS, this._renderer.toModelCoords(this.node_paper_coords.add(_delta)));
+    this._element.setPosition(this._renderer.toModelCoords(this.node_paper_coords.add(_delta)));
+    this._renderer._project.serializer.save();
     this._renderer.redraw();
 }
 
+Rkns.Renderers.Paper__Controllers.Node.prototype.select = function(_delta) {
+    this.node_circle.strokeWidth = 3;
+}
+
+Rkns.Renderers.Paper__Controllers.Node.prototype.unselect = function(_delta) {
+    this.node_circle.strokeWidth = 1;
+}
+
 /* */
 
 Rkns.Renderers.Paper__Controllers.Edge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
 
-
 Rkns.Renderers.Paper__Controllers.Edge.prototype._init = function() {
     this._renderer.edge_layer.activate();
     this.type = "edge";
@@ -55,33 +67,51 @@
     this.edge_line = new paper.Path();
     this.edge_line.add([0,0],[0,0]);
     this.edge_line.__controller = this;
+    this.edge_arrow = new paper.Path();
+    this.edge_arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
+    this.edge_arrow.__controller = this;
     this.edge_text = new paper.PointText();
     this.edge_text.characterStyle = {
-        fontSize: 10,
+        fontSize: Rkns._EDGE_FONT_SIZE,
         fillColor: 'black'
     };
     this.edge_text.paragraphStyle.justification = 'center';
     this.edge_text.__controller = this;
-    this.edge_angle = 0;
+    this.edge_text_angle = 0;
+    this.edge_arrow_angle = 0;
 }
 
 Rkns.Renderers.Paper__Controllers.Edge.prototype.redraw = function() {
-    this.edge_line.strokeColor = this._element.created_by.color;
     var _p0 = this.from_node_controller.node_paper_coords,
         _p1 = this.to_node_controller.node_paper_coords,
-        _a = _p1.subtract(_p0).angle;
+        _a = _p1.subtract(_p0).angle,
+        _center = _p0.add(_p1).divide(2),
+        _color = this._element.created_by.color;
+    this.edge_line.strokeColor = _color;
     this.edge_line.segments[0].point = _p0;
     this.edge_line.segments[1].point = _p1;
-    this.edge_text.content = this._element.title;
-    this.edge_text.position = _p0.add(_p1).divide(2);
+    this.edge_arrow.rotate(_a - this.edge_arrow_angle);
+    this.edge_arrow.fillColor = _color;
+    this.edge_arrow.position = _center;
+    this.edge_arrow_angle = _a;
     if (_a > 90) {
         _a -= 180;
     }
     if (_a < -90) {
         _a += 180;
     }
-    this.edge_text.rotate(_a - this.edge_angle);
-    this.edge_angle = _a;
+    this.edge_text.rotate(_a - this.edge_text_angle);
+    this.edge_text.content = this._element.title;
+    this.edge_text.position = _center;
+    this.edge_text_angle = _a;
+}
+
+Rkns.Renderers.Paper__Controllers.Edge.prototype.select = function(_delta) {
+    this.edge_line.strokeWidth = 3;
+}
+
+Rkns.Renderers.Paper__Controllers.Edge.prototype.unselect = function(_delta) {
+    this.edge_line.strokeWidth = 1;
 }
 
 Rkns.Renderers.Paper__Controllers.Edge.prototype.paperShift = function(_delta) {
@@ -89,28 +119,94 @@
     this.to_node_controller.paperShift(_delta);
     this._renderer.redraw();
 }
+/* */
+
+Rkns.Renderers.Paper__Controllers.TempEdge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
+
+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;
+    this.edge_line = new paper.Path();
+    this.edge_line.strokeColor = _color;
+    this.edge_line.add([0,0],[0,0]);
+    this.edge_line.__controller = this;
+    this.edge_arrow = new paper.Path();
+    this.edge_arrow.fillColor = _color;
+    this.edge_arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
+    this.edge_arrow.__controller = this;
+    this.edge_arrow_angle = 0;
+}
+
+Rkns.Renderers.Paper__Controllers.TempEdge.prototype.redraw = function() {
+    var _p0 = this.from_node_controller.node_paper_coords,
+        _p1 = this.end_pos,
+        _a = _p1.subtract(_p0).angle,
+        _c = _p0.add(_p1).divide(2);
+    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.position = _c;
+    this.edge_arrow_angle = _a;
+}
+
+Rkns.Renderers.Paper__Controllers.TempEdge.prototype.paperShift = function(_delta) {
+    this.end_pos = this.end_pos.add(_delta);
+    this._renderer.onMouseMove({point: this.end_pos});
+    this.redraw();
+}
+
+Rkns.Renderers.Paper__Controllers.TempEdge.prototype.finishEdge = function(_event) {
+    var _hitResult = paper.project.hitTest(_event.point);
+    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({
+                from: this.from_node_controller._element.id,
+                to: _target._element.id
+            }, Rkns._RENDER_AND_SAVE)
+        }
+    }
+    this.edge_arrow.remove();
+    this.edge_line.remove();
+    this._renderer.controllers.removeId(this.id);
+}
 
 /* */
 
 Rkns.Renderers.Paper.prototype._init = function() {
-    paper.setup(document.getElementById(this._project._opts.canvas_id));
+    this._MARGIN_X = 80;
+    this._MARGIN_Y = 50;
+    var _canvas_id = this._project._opts.canvas_id;
+    this.$ = Rkns.$("#"+_canvas_id)
+    paper.setup(document.getElementById(_canvas_id));
     this.scale = 1;
     this.offset = paper.view.center;
     this.totalScroll = 0;
     this.dragging_target = null;
+    this.selected_target = null;
     this.edge_layer = new paper.Layer();
     this.node_layer = new paper.Layer();
     var _tool = new paper.Tool(),
         _this = this;
+    _tool.onMouseMove = function(_event) {
+        _this.onMouseMove(_event);
+    }
     _tool.onMouseDown = function(_event) {
         _this.onMouseDown(_event);
     }
     _tool.onMouseDrag = function(_event) {
         _this.onMouseDrag(_event);
     }
-    Rkns.$("#"+this._project._opts.canvas_id).mousewheel(function(_event, _delta) {
+    _tool.onMouseUp = function(_event) {
+        _this.onMouseUp(_event);
+    }
+    this.$.mousewheel(function(_event, _delta) {
         _this.onScroll(_event, _delta);
     })
+    this.$.dblclick(function(_event) {
+        _this.onDoubleClick(_event);
+    })
     paper.view.onResize = function(_event) {
         _this.offset = _this.offset.add(_event.delta.divide(2));
         _this.redraw();
@@ -134,32 +230,61 @@
         _miny = Math.min.apply(Math, _yy),
         _maxx = Math.max.apply(Math, _xx),
         _maxy = Math.max.apply(Math, _yy);
-    this.scale = Math.min((paper.view.size.width - 160) / (_maxx - _minx), (paper.view.size.height - 100) / (_maxy - _miny));
+    this.scale = Math.min((paper.view.size.width - 2 * this._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * this._MARGIN_Y) / (_maxy - _miny));
     this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(this.scale));
-    this.nodes = this._project.nodes.map(function(_node) {
-        return new Rkns.Renderers.Paper__Controllers.Node(_this, _node);
+    this.controllers = new Rkns.Model.List();
+    this._project.nodes.forEach(function(_node) {
+        _this.addElement("Node", _node);
     });
-    this.edges = this._project.edges.map(function(_edge) {
-        return new Rkns.Renderers.Paper__Controllers.Edge(_this, _edge);
+    this._project.edges.forEach(function(_edge) {
+        _this.addElement("Edge", _edge);
     });
     
     this.redraw();
 }
 
+Rkns.Renderers.Paper.prototype.addElement = function(_type, _element) {
+    var _el = new Rkns.Renderers.Paper__Controllers[_type](this, _element);
+    this.controllers.push(_el);
+    return _el;
+}
+
 Rkns.Renderers.Paper.prototype.redraw = function() {
-    Rkns._(this.nodes).each(function(_node) {
-        _node.redraw();
-    });
-    Rkns._(this.edges).each(function(_edge) {
-        _edge.redraw();
+    this.controllers.forEach(function(_controller) {
+        _controller.redraw();
     });
     paper.view.draw();
 }
 
+Rkns.Renderers.Paper.prototype.onMouseMove = function(_event) {
+    var _hitResult = paper.project.hitTest(_event.point);
+    if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
+        if (this.selected_target !== _hitResult.item.__controller) {
+            if (this.selected_target) {
+                this.selected_target.unselect();
+            }
+            this.selected_target = _hitResult.item.__controller;
+            this.selected_target.select();
+        }
+    } else {
+        if (this.selected_target) {
+            this.selected_target.unselect();
+        }
+        this.selected_target = null;
+    }
+}
+
 Rkns.Renderers.Paper.prototype.onMouseDown = function(_event) {
     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",{});
+            _tmpEdge.end_pos = _event.point;
+            _tmpEdge.from_node_controller = this.dragging_target;
+            _tmpEdge.redraw();
+            this.dragging_target = _tmpEdge;
+        }
     } else {
         this.dragging_target = null;
     }
@@ -174,10 +299,17 @@
     }
 }
 
+Rkns.Renderers.Paper.prototype.onMouseUp = function(_event) {
+    if (this.dragging_target && this.dragging_target.type === "temp-edge") {
+        this.dragging_target.finishEdge(_event);
+    }
+    this.dragging_target = null;
+}
+
 Rkns.Renderers.Paper.prototype.onScroll = function(_event, _scrolldelta) {
     this.totalScroll += _scrolldelta;
     if (Math.abs(this.totalScroll) >= 1) {
-        var _off = Rkns.$("#"+this._project._opts.canvas_id).offset(),
+        var _off = this.$.offset(),
             _delta = new paper.Point([
                 _event.pageX - _off.left,
                 _event.pageY - _off.top
@@ -193,3 +325,22 @@
         this.redraw();
     }
 }
+
+Rkns.Renderers.Paper.prototype.onDoubleClick = function(_event) {
+    var _off = this.$.offset(),
+        _point = new paper.Point([
+            _event.pageX - _off.left,
+            _event.pageY - _off.top
+        ]);
+    var _hitResult = paper.project.hitTest(_point);
+    if (!_hitResult || typeof _hitResult.item.__controller === "undefined") {
+        var _coords = this.toModelCoords(_point);
+        this._project.addNode({
+            position: {
+                x: _coords.x,
+                y: _coords.y
+            }
+        }, Rkns._RENDER_AND_SAVE);
+    }
+    paper.view.draw();
+}