client/js/paper-renderer.js
changeset 7 ae86ecebb1be
parent 6 a7b54105f74e
child 8 8e67c9f6da51
equal deleted inserted replaced
6:a7b54105f74e 7:ae86ecebb1be
     1 Rkns.Renderers.Paper = Rkns.Utils.inherit(Rkns.Renderers._Base);
     1 Rkns.Renderer = {}
     2 
     2 
     3 Rkns.Renderers.Paper__Utils = {
     3 Rkns.Renderer.Utils = {
     4     _EDITOR_ARROW_LENGTH : 20,
     4     _EDITOR_ARROW_LENGTH : 20,
     5     _EDITOR_ARROW_WIDTH : 40,
     5     _EDITOR_ARROW_WIDTH : 40,
     6     _EDITOR_MARGIN : 15,
     6     _EDITOR_MARGIN : 15,
     7     _EDITOR_PADDING : 10,
     7     _EDITOR_PADDING : 10,
     8     _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0']),
     8     _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0']),
    41         _path.fillColor = new paper.GradientColor(this._EDITOR_GRADIENT, [0,_top], [0, _bottom])
    41         _path.fillColor = new paper.GradientColor(this._EDITOR_GRADIENT, [0,_top], [0, _bottom])
    42         return {
    42         return {
    43             left: (this._EDITOR_PADDING + Math.min(_left, _right)),
    43             left: (this._EDITOR_PADDING + Math.min(_left, _right)),
    44             top: (this._EDITOR_PADDING + _top)
    44             top: (this._EDITOR_PADDING + _top)
    45         }
    45         }
    46     }
    46     },
    47 }
    47     sector : function(_inR, _outR, _startAngle, _endAngle, _padding, _imgsrc) {
    48 
    48         _path = new paper.Path();
    49 Rkns.Renderers.Paper__Controllers = {}
    49         var _startRads = _startAngle * Math.PI / 180,
    50 
    50             _endRads = _endAngle * Math.PI / 180,
    51 Rkns.Renderers.Paper__Controllers._Base = function(_renderer, _element) {
    51             _img = new Image(),
       
    52             _span = _endRads - _startRads,
       
    53             _k = .0879 * _span,
       
    54             _kin = _k * _inR,
       
    55             _kout = _k * _outR,
       
    56             _startdx = - Math.sin(_startRads),
       
    57             _startdy = Math.cos(_startRads),
       
    58             _startXIn = Math.cos(_startRads) * _inR + _padding * _startdx,
       
    59             _startYIn = Math.sin(_startRads) * _inR + _padding * _startdy,
       
    60             _startXOut = Math.cos(_startRads) * _outR + _padding * _startdx,
       
    61             _startYOut = Math.sin(_startRads) * _outR + _padding * _startdy,
       
    62             _enddx = - Math.sin(_endRads),
       
    63             _enddy = Math.cos(_endRads),
       
    64             _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx,
       
    65             _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy,
       
    66             _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx,
       
    67             _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy,
       
    68             _centerR = (_inR + _outR)/2,
       
    69             _centerRads = (_startRads + _endRads) / 2,
       
    70             _centerX = Math.cos(_centerRads) * _centerR,
       
    71             _centerY = Math.sin(_centerRads) * _centerR,
       
    72             _segments = [];
       
    73         _segments.push([[_startXIn, _startYIn], [0, 0], [ _kin * _startdx, _kin * _startdy ]]);
       
    74         for (var i = 1; i < 4; i++) {
       
    75             var _rads = i * _span / 4 + _startRads,
       
    76                 _dx = - Math.sin(_rads),
       
    77                 _dy = Math.cos(_rads),
       
    78                 _x = Math.cos(_rads) * _inR,
       
    79                 _y = Math.sin(_rads) * _inR;
       
    80             _segments.push([[_x, _y], [ - _kin * _dx, - _kin * _dy], [ _kin * _dx, _kin * _dy ]]);
       
    81         }
       
    82         _segments.push([[_endXIn, _endYIn], [ - _kin * _enddx, - _kin * _enddy ], [0,0]]);
       
    83         _segments.push([[_endXOut, _endYOut], [ 0,0 ], [ - _kout * _enddx, - _kout * _enddy ]]);
       
    84         for (var i = 3; i > 0; i--) {
       
    85             var _rads = i * _span / 4 + _startRads,
       
    86                 _dx = - Math.sin(_rads),
       
    87                 _dy = Math.cos(_rads),
       
    88                 _x = Math.cos(_rads) * _outR,
       
    89                 _y = Math.sin(_rads) * _outR;
       
    90             _segments.push([[_x, _y], [ _kout * _dx, _kout * _dy], [ - _kout * _dx, - _kout * _dy ]]);
       
    91         }
       
    92         _segments.push([[_startXOut, _startYOut], [ _kout * _startdx, _kout * _startdy ], [0, 0]]);
       
    93         _path.add.apply(_path, _segments);
       
    94         _path.fillColor = "#333333";
       
    95         _path.closed = true;
       
    96         var _grp = new paper.Group([_path]),
       
    97             _res = {
       
    98                 group: _grp,
       
    99                 circle: _path,
       
   100                 delta: new paper.Point(0,0),
       
   101                 img: _img,
       
   102                 imgdelta: new paper.Point([_centerX, _centerY])
       
   103             }
       
   104         _img.onload = function() {
       
   105             var _w = _img.width,
       
   106                 _h = _img.height;
       
   107             var _raster = new paper.Raster(_img);
       
   108             _raster.position = _res.imgdelta.add(_grp.position).subtract(_res.delta);
       
   109             _grp.addChild(_raster);
       
   110         }
       
   111         _img.src = _imgsrc;
       
   112         return _res
       
   113     }
       
   114 }
       
   115 
       
   116 Rkns.Renderer._BaseController = function(_renderer, _element) {
    52     if (typeof _renderer !== "undefined") {
   117     if (typeof _renderer !== "undefined") {
    53         this.id = Rkns.Utils.getUID('controller');
   118         this.id = Rkns.Utils.getUID('controller');
    54         this._renderer = _renderer;
   119         this._renderer = _renderer;
    55         this._project = _renderer._project;
   120         this._project = _renderer._project;
    56         this._element = _element;
   121         this._element = _element;
    57         this._element.__controller = this;
   122         this._element.__controller = this;
    58     }
   123     }
    59 }
   124 }
    60 
   125 
    61 Rkns.Renderers.Paper__Controllers._Base.prototype.select = function() {}
   126 Rkns.Renderer._BaseController.prototype.select = function() {}
    62 
   127 
    63 Rkns.Renderers.Paper__Controllers._Base.prototype.unselect = function() {}
   128 Rkns.Renderer._BaseController.prototype.unselect = function() {}
    64 
   129 
    65 Rkns.Renderers.Paper__Controllers._Base.prototype.destroy = function() {}
   130 Rkns.Renderer._BaseController.prototype.mouseup = function() {}
    66 
   131 
    67 Rkns.Renderers.Paper__Controllers.Node = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
   132 Rkns.Renderer._BaseController.prototype.destroy = function() {}
    68 
   133 
    69 Rkns.Renderers.Paper__Controllers.Node.prototype._init = function() {
   134 Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
       
   135 
       
   136 Rkns.Renderer.Node.prototype._init = function() {
    70     this._renderer.node_layer.activate();
   137     this._renderer.node_layer.activate();
    71     this.type = "node";
   138     this.type = "node";
    72     this.node_circle = new paper.Path.Circle([0, 0], Rkns._NODE_RADIUS);
   139     this.circle = new paper.Path.Circle([0, 0], Rkns._NODE_RADIUS);
    73     this.node_circle.fillColor = '#ffffff';
   140     this.circle.fillColor = '#ffffff';
    74     this.node_circle.__controller = this;
   141     this.circle.opacity = .9;
    75     this.node_text = new paper.PointText([0,0]);
   142     this.circle.__controller = this;
    76     this.node_text.characterStyle = {
   143     this.title = new paper.PointText([0,0]);
       
   144     this.title.characterStyle = {
    77         fontSize: Rkns._NODE_FONT_SIZE,
   145         fontSize: Rkns._NODE_FONT_SIZE,
    78         fillColor: 'black'
   146         fillColor: 'black'
    79     };
   147     };
    80     this.node_text.paragraphStyle.justification = 'center';
   148     this.edit_button = new Rkns.Renderer.NodeEditButton(this._renderer, {});
    81     this.node_text.__controller = this;
   149     this.edit_button.node_controller = this;
    82 }
   150     this.remove_button = new Rkns.Renderer.NodeRemoveButton(this._renderer, {});
    83 
   151     this.remove_button.node_controller = this;
    84 Rkns.Renderers.Paper__Controllers.Node.prototype.redraw = function() {
   152     this.title.paragraphStyle.justification = 'center';
    85     this.node_model_coords = new paper.Point(this._element.position);
   153     this.title.__controller = this;
    86     this.node_paper_coords = this._renderer.toPaperCoords(this.node_model_coords);
   154 }
    87     this.node_circle.position = this.node_paper_coords;
   155 
    88     this.node_text.content = this._element.title;
   156 Rkns.Renderer.Node.prototype.redraw = function() {
    89     this.node_text.position = this.node_paper_coords.add([0, 2 * Rkns._NODE_RADIUS]);
   157     var _model_coords = new paper.Point(this._element.position);
    90     this.node_circle.strokeColor = this._element.created_by.color;
   158     this.paper_coords = this._renderer.toPaperCoords(_model_coords);
    91 }
   159     this.circle.position = this.paper_coords;
    92 
   160     this.title.content = this._element.title;
    93 Rkns.Renderers.Paper__Controllers.Node.prototype.paperShift = function(_delta) {
   161     this.title.position = this.paper_coords.add([0, 2 * Rkns._NODE_RADIUS]);
    94     var _coords = this._renderer.toModelCoords(this.node_paper_coords.add(_delta)),
   162     this.circle.strokeColor = this._element.created_by.color;
       
   163     this.edit_button.moveTo(this.paper_coords);
       
   164     this.remove_button.moveTo(this.paper_coords);
       
   165 }
       
   166 
       
   167 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
       
   168     var _coords = this._renderer.toModelCoords(this.paper_coords.add(_delta)),
    95         _data = {
   169         _data = {
    96             position: {
   170             position: {
    97                 x: _coords.x,
   171                 x: _coords.x,
    98                 y: _coords.y
   172                 y: _coords.y
    99             }
   173             }
   100         };
   174         };
   101     this._project.updateElement(this._element, _data, Rkns._SAVE);
   175     this._project.updateElement(this._element, _data, Rkns._SAVE);
   102     this._renderer.redraw();
   176     this._renderer.redraw();
   103 }
   177 }
   104 
   178 
   105 Rkns.Renderers.Paper__Controllers.Node.prototype.select = function(_delta) {
   179 Rkns.Renderer.Node.prototype.select = function() {
   106     this.node_circle.strokeWidth = 3;
   180     this.circle.strokeWidth = 3;
   107 }
   181     this.edit_button.show();
   108 
   182     this.remove_button.show();
   109 Rkns.Renderers.Paper__Controllers.Node.prototype.unselect = function(_delta) {
   183 }
   110     this.node_circle.strokeWidth = 1;
   184 
       
   185 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
       
   186     if (!_newTarget || (_newTarget !== this.edit_button && _newTarget !== this.remove_button)) {
       
   187         this.edit_button.hide();
       
   188         this.remove_button.hide();
       
   189     }
       
   190     this.circle.strokeWidth = 1;
       
   191 }
       
   192 
       
   193 Rkns.Renderer.Node.prototype.mouseup = function(_event) {
       
   194     if (!this._renderer.is_dragging) {
       
   195         this._renderer.removeControllersOfType("editor");
       
   196         var _editor = this._renderer.addController("NodeEditor",{});
       
   197         _editor.node_controller = this;
       
   198         _editor.redraw();
       
   199     }
       
   200 }
       
   201 
       
   202 Rkns.Renderer.Node.prototype.destroy = function(_event) {
       
   203     this.edit_button.destroy();
       
   204     this.remove_button.destroy();
       
   205     this.circle.remove();
       
   206     this.title.remove();
   111 }
   207 }
   112 
   208 
   113 /* */
   209 /* */
   114 
   210 
   115 Rkns.Renderers.Paper__Controllers.Edge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
   211 Rkns.Renderer.Edge = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
   116 
   212 
   117 Rkns.Renderers.Paper__Controllers.Edge.prototype._init = function() {
   213 Rkns.Renderer.Edge.prototype._init = function() {
   118     this._renderer.edge_layer.activate();
   214     this._renderer.edge_layer.activate();
   119     this.type = "edge";
   215     this.type = "edge";
   120     this.from_node_controller = this._element.from.__controller;
   216     this.from_controller = this._element.from.__controller;
   121     this.to_node_controller = this._element.to.__controller;
   217     this.to_node_controller = this._element.to.__controller;
   122     this.edge_line = new paper.Path();
   218     this.line = new paper.Path();
   123     this.edge_line.add([0,0],[0,0]);
   219     this.line.add([0,0],[0,0]);
   124     this.edge_line.__controller = this;
   220     this.line.__controller = this;
   125     this.edge_arrow = new paper.Path();
   221     this.arrow = new paper.Path();
   126     this.edge_arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
   222     this.arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
   127     this.edge_arrow.__controller = this;
   223     this.arrow.__controller = this;
   128     this.edge_text = new paper.PointText();
   224     this.text = new paper.PointText();
   129     this.edge_text.characterStyle = {
   225     this.text.characterStyle = {
   130         fontSize: Rkns._EDGE_FONT_SIZE,
   226         fontSize: Rkns._EDGE_FONT_SIZE,
   131         fillColor: 'black'
   227         fillColor: 'black'
   132     };
   228     };
   133     this.edge_text.paragraphStyle.justification = 'center';
   229     this.text.paragraphStyle.justification = 'center';
   134     this.edge_text.__controller = this;
   230     this.text.__controller = this;
   135     this.edge_text_angle = 0;
   231     this.text_angle = 0;
   136     this.edge_arrow_angle = 0;
   232     this.arrow_angle = 0;
   137 }
   233 }
   138 
   234 
   139 Rkns.Renderers.Paper__Controllers.Edge.prototype.redraw = function() {
   235 Rkns.Renderer.Edge.prototype.redraw = function() {
   140     var _p0 = this.from_node_controller.node_paper_coords,
   236     var _p0 = this.from_controller.paper_coords,
   141         _p1 = this.to_node_controller.node_paper_coords,
   237         _p1 = this.to_node_controller.paper_coords,
   142         _a = _p1.subtract(_p0).angle,
   238         _a = _p1.subtract(_p0).angle,
   143         _color = this._element.created_by.color;
   239         _color = this._element.created_by.color;
   144     this.edge_paper_coords = _p0.add(_p1).divide(2);
   240     this.edge_paper_coords = _p0.add(_p1).divide(2);
   145     this.edge_line.strokeColor = _color;
   241     this.line.strokeColor = _color;
   146     this.edge_line.segments[0].point = _p0;
   242     this.line.segments[0].point = _p0;
   147     this.edge_line.segments[1].point = _p1;
   243     this.line.segments[1].point = _p1;
   148     this.edge_arrow.rotate(_a - this.edge_arrow_angle);
   244     this.arrow.rotate(_a - this.arrow_angle);
   149     this.edge_arrow.fillColor = _color;
   245     this.arrow.fillColor = _color;
   150     this.edge_arrow.position = this.edge_paper_coords;
   246     this.arrow.position = this.edge_paper_coords;
   151     this.edge_arrow_angle = _a;
   247     this.arrow_angle = _a;
   152     if (_a > 90) {
   248     if (_a > 90) {
   153         _a -= 180;
   249         _a -= 180;
   154     }
   250     }
   155     if (_a < -90) {
   251     if (_a < -90) {
   156         _a += 180;
   252         _a += 180;
   157     }
   253     }
   158     this.edge_text.rotate(_a - this.edge_text_angle);
   254     this.text.rotate(_a - this.text_angle);
   159     this.edge_text.content = this._element.title;
   255     this.text.content = this._element.title;
   160     this.edge_text.position = this.edge_paper_coords;
   256     this.text.position = this.edge_paper_coords;
   161     this.edge_text_angle = _a;
   257     this.text_angle = _a;
   162 }
   258 }
   163 
   259 
   164 Rkns.Renderers.Paper__Controllers.Edge.prototype.select = function(_delta) {
   260 Rkns.Renderer.Edge.prototype.select = function() {
   165     this.edge_line.strokeWidth = 3;
   261     this.line.strokeWidth = 3;
   166 }
   262 }
   167 
   263 
   168 Rkns.Renderers.Paper__Controllers.Edge.prototype.unselect = function(_delta) {
   264 Rkns.Renderer.Edge.prototype.unselect = function(_newTarget) {
   169     this.edge_line.strokeWidth = 1;
   265     this.line.strokeWidth = 1;
   170 }
   266 }
   171 
   267 
   172 Rkns.Renderers.Paper__Controllers.Edge.prototype.paperShift = function(_delta) {
   268 Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
   173     this.from_node_controller.paperShift(_delta);
   269     if (!this._renderer.is_dragging) {
       
   270         this._renderer.removeControllersOfType("editor");
       
   271         var _editor = this._renderer.addController("EdgeEditor",{});
       
   272         _editor.edge_controller = this;
       
   273         _editor.redraw();
       
   274     }
       
   275 }
       
   276 
       
   277 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
       
   278     this.from_controller.paperShift(_delta);
   174     this.to_node_controller.paperShift(_delta);
   279     this.to_node_controller.paperShift(_delta);
   175     this._renderer.redraw();
   280     this._renderer.redraw();
   176 }
   281 }
   177 
   282 
       
   283 Rkns.Renderer.Edge.prototype.destroy = function() {
       
   284     this.line.remove();
       
   285     this.arrow.remove();
       
   286     this.text.remove();
       
   287 }
       
   288 
   178 /* */
   289 /* */
   179 
   290 
   180 Rkns.Renderers.Paper__Controllers.TempEdge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
   291 Rkns.Renderer.TempEdge = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
   181 
   292 
   182 Rkns.Renderers.Paper__Controllers.TempEdge.prototype._init = function() {
   293 Rkns.Renderer.TempEdge.prototype._init = function() {
   183     this._renderer.edge_layer.activate();
   294     this._renderer.edge_layer.activate();
   184     this.type = "temp-edge";
   295     this.type = "temp-edge";
   185     var _color = this._project.current_user.color;
   296     var _color = this._project.current_user.color;
   186     this.edge_line = new paper.Path();
   297     this.line = new paper.Path();
   187     this.edge_line.strokeColor = _color;
   298     this.line.strokeColor = _color;
   188     this.edge_line.add([0,0],[0,0]);
   299     this.line.add([0,0],[0,0]);
   189     this.edge_line.__controller = this;
   300     this.line.__controller = this;
   190     this.edge_arrow = new paper.Path();
   301     this.arrow = new paper.Path();
   191     this.edge_arrow.fillColor = _color;
   302     this.arrow.fillColor = _color;
   192     this.edge_arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
   303     this.arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
   193     this.edge_arrow.__controller = this;
   304     this.arrow.__controller = this;
   194     this.edge_arrow_angle = 0;
   305     this.arrow_angle = 0;
   195 }
   306 }
   196 
   307 
   197 Rkns.Renderers.Paper__Controllers.TempEdge.prototype.redraw = function() {
   308 Rkns.Renderer.TempEdge.prototype.redraw = function() {
   198     var _p0 = this.from_node_controller.node_paper_coords,
   309     var _p0 = this.from_controller.paper_coords,
   199         _p1 = this.end_pos,
   310         _p1 = this.end_pos,
   200         _a = _p1.subtract(_p0).angle,
   311         _a = _p1.subtract(_p0).angle,
   201         _c = _p0.add(_p1).divide(2);
   312         _c = _p0.add(_p1).divide(2);
   202     this.edge_line.segments[0].point = _p0;
   313     this.line.segments[0].point = _p0;
   203     this.edge_line.segments[1].point = _p1;
   314     this.line.segments[1].point = _p1;
   204     this.edge_arrow.rotate(_a - this.edge_arrow_angle);
   315     this.arrow.rotate(_a - this.arrow_angle);
   205     this.edge_arrow.position = _c;
   316     this.arrow.position = _c;
   206     this.edge_arrow_angle = _a;
   317     this.arrow_angle = _a;
   207 }
   318 }
   208 
   319 
   209 Rkns.Renderers.Paper__Controllers.TempEdge.prototype.paperShift = function(_delta) {
   320 Rkns.Renderer.TempEdge.prototype.paperShift = function(_delta) {
   210     this.end_pos = this.end_pos.add(_delta);
   321     this.end_pos = this.end_pos.add(_delta);
   211     this._renderer.onMouseMove({point: this.end_pos});
   322     this._renderer.onMouseMove({point: this.end_pos});
   212     this.redraw();
   323     this.redraw();
   213 }
   324 }
   214 
   325 
   215 Rkns.Renderers.Paper__Controllers.TempEdge.prototype.finishEdge = function(_event) {
   326 Rkns.Renderer.TempEdge.prototype.mouseup = function(_event) {
   216     var _hitResult = paper.project.hitTest(_event.point);
   327     var _hitResult = paper.project.hitTest(_event.point);
   217     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
   328     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
   218         var _target = _hitResult.item.__controller;
   329         var _target = _hitResult.item.__controller;
   219         if (_target.type === "node" && this.from_node_controller._element.id !== _target._element.id) {
   330         if (_target.type === "node" && this.from_controller._element.id !== _target._element.id) {
   220             this._project.addEdge({
   331             this._project.addEdge({
   221                 from: this.from_node_controller._element.id,
   332                 from: this.from_controller._element.id,
   222                 to: _target._element.id
   333                 to: _target._element.id
   223             }, Rkns._RENDER_AND_SAVE)
   334             }, Rkns._RENDER_AND_SAVE)
   224         }
   335         }
   225     }
   336     }
   226     this._renderer.removeController(this);
   337     this._renderer.removeController(this);
   227 }
   338 }
   228 
   339 
   229 Rkns.Renderers.Paper__Controllers.TempEdge.prototype.destroy = function() {
   340 Rkns.Renderer.TempEdge.prototype.destroy = function() {
   230     this.edge_arrow.remove();
   341     this.arrow.remove();
   231     this.edge_line.remove();
   342     this.line.remove();
   232 }
   343 }
   233 
   344 
   234 /* */
   345 /* */
   235 
   346 
   236 Rkns.Renderers.Paper__Controllers.NodeEditor = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
   347 Rkns.Renderer.NodeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
   237 
   348 
   238 Rkns.Renderers.Paper__Controllers.NodeEditor.prototype._init = function() {
   349 Rkns.Renderer.NodeEditor.prototype._init = function() {
   239     this._renderer.overlay_layer.activate();
   350     this._renderer.overlay_layer.activate();
   240     this.type = "editor";
   351     this.type = "editor";
   241     this.editor_block = new paper.Path();
   352     this.editor_block = new paper.Path();
   242     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   353     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   243     this.editor_block.add.apply(this.editor_block, _pts);
   354     this.editor_block.add.apply(this.editor_block, _pts);
   252             opacity: .8
   363             opacity: .8
   253         })
   364         })
   254         .hide();
   365         .hide();
   255 }
   366 }
   256 
   367 
   257 Rkns.Renderers.Paper__Controllers.NodeEditor.prototype.template = Rkns._.template(
   368 Rkns.Renderer.NodeEditor.prototype.template = Rkns._.template(
   258     '<h2><span class="Rk-CloseX">&times;</span><%=l10n.edit_node%></span></h2>'
   369     '<h2><span class="Rk-CloseX">&times;</span><%=l10n.edit_node%></span></h2>'
   259     + '<p><label><%=l10n.edit_title%></label><input class="Rk-Edit-Title" type="text" value="<%=node.title%>"/></p>'
   370     + '<p><label><%=l10n.edit_title%></label><input class="Rk-Edit-Title" type="text" value="<%=node.title%>"/></p>'
   260     + '<p><label><%=l10n.edit_uri%></label><input class="Rk-Edit-URI" type="text" value="<%=node.uri%>"/></p>'
   371     + '<p><label><%=l10n.edit_uri%></label><input class="Rk-Edit-URI" type="text" value="<%=node.uri%>"/></p>'
   261     + '<p><label><%=l10n.edit_description%></label><textarea class="Rk-Edit-Description"><%=node.description%></textarea></p>'
   372     + '<p><label><%=l10n.edit_description%></label><textarea class="Rk-Edit-Description"><%=node.description%></textarea></p>'
   262     + '<p><label><%=l10n.created_by%></label> <span class="Rk-UserColor" style="background:<%=node.created_by.color%>;"></span> <%=node.created_by.title%></p>'
   373     + '<p><label><%=l10n.created_by%></label> <span class="Rk-UserColor" style="background:<%=node.created_by.color%>;"></span> <%=node.created_by.title%></p>'
   263 );
   374 );
   264 
   375 
   265 Rkns.Renderers.Paper__Controllers.NodeEditor.prototype.redraw = function() {
   376 Rkns.Renderer.NodeEditor.prototype.redraw = function() {
   266     var _coords = this.node_controller.node_paper_coords,
   377     var _coords = this.node_controller.paper_coords,
   267         _element = this.node_controller._element,
   378         _element = this.node_controller._element,
   268         _css = Rkns.Renderers.Paper__Utils.drawEditBox(_coords, this.editor_block, 250, 300);
   379         _css = Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 300);
   269     this.editor_$
   380     this.editor_$
   270         .html(this.template({
   381         .html(this.template({
   271             node: _element,
   382             node: _element,
   272             l10n: this._project.l10n
   383             l10n: this._project.l10n
   273         }))
   384         }))
   292         _this.node_controller.redraw();
   403         _this.node_controller.redraw();
   293         paper.view.draw();
   404         paper.view.draw();
   294     });
   405     });
   295 }
   406 }
   296 
   407 
   297 Rkns.Renderers.Paper__Controllers.NodeEditor.prototype.destroy = function() {
   408 Rkns.Renderer.NodeEditor.prototype.destroy = function() {
   298     this.editor_block.remove();
   409     this.editor_block.remove();
   299     this.editor_$.detach();
   410     this.editor_$.detach();
   300 }
   411 }
   301 
   412 
   302 
       
   303 /* */
   413 /* */
   304 
   414 
   305 Rkns.Renderers.Paper__Controllers.EdgeEditor = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
   415 Rkns.Renderer.EdgeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
   306 
   416 
   307 Rkns.Renderers.Paper__Controllers.EdgeEditor.prototype._init = function() {
   417 Rkns.Renderer.EdgeEditor.prototype._init = function() {
   308     this._renderer.overlay_layer.activate();
   418     this._renderer.overlay_layer.activate();
   309     this.type = "editor";
   419     this.type = "editor";
   310     this.editor_block = new paper.Path();
   420     this.editor_block = new paper.Path();
   311     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   421     var _pts = Rkns._(Rkns._.range(8)).map(function() {return [0,0]});
   312     this.editor_block.add.apply(this.editor_block, _pts);
   422     this.editor_block.add.apply(this.editor_block, _pts);
   321             opacity: .8
   431             opacity: .8
   322         })
   432         })
   323         .hide();
   433         .hide();
   324 }
   434 }
   325 
   435 
   326 Rkns.Renderers.Paper__Controllers.EdgeEditor.prototype.template = Rkns._.template(
   436 Rkns.Renderer.EdgeEditor.prototype.template = Rkns._.template(
   327     '<h2><span class="Rk-CloseX">&times;</span><%=l10n.edit_edge%></span></h2>'
   437     '<h2><span class="Rk-CloseX">&times;</span><%=l10n.edit_edge%></span></h2>'
   328     + '<p><label><%=l10n.edit_title%></label><input class="Rk-Edit-Title" type="text" value="<%=edge.title%>"/></p>'
   438     + '<p><label><%=l10n.edit_title%></label><input class="Rk-Edit-Title" type="text" value="<%=edge.title%>"/></p>'
   329     + '<p><label><%=l10n.edit_uri%></label><input class="Rk-Edit-URI" type="text" value="<%=edge.uri%>"/></p>'
   439     + '<p><label><%=l10n.edit_uri%></label><input class="Rk-Edit-URI" type="text" value="<%=edge.uri%>"/></p>'
   330     + '<p><label><%=l10n.edit_from%></label><span class="Rk-UserColor" style="background:<%=edge.from.created_by.color%>;"></span><%=edge.from.title%></p>'
   440     + '<p><label><%=l10n.edit_from%></label><span class="Rk-UserColor" style="background:<%=edge.from.created_by.color%>;"></span><%=edge.from.title%></p>'
   331     + '<p><label><%=l10n.edit_to%></label><span class="Rk-UserColor" style="background:<%=edge.to.created_by.color%>;"></span><%=edge.to.title%></p>'
   441     + '<p><label><%=l10n.edit_to%></label><span class="Rk-UserColor" style="background:<%=edge.to.created_by.color%>;"></span><%=edge.to.title%></p>'
   332     + '<p><label><%=l10n.created_by%> </label><span class="Rk-UserColor" style="background:<%=edge.created_by.color%>;"></span> <%=edge.created_by.title%></p>'
   442     + '<p><label><%=l10n.created_by%> </label><span class="Rk-UserColor" style="background:<%=edge.created_by.color%>;"></span> <%=edge.created_by.title%></p>'
   333 );
   443 );
   334 
   444 
   335 Rkns.Renderers.Paper__Controllers.EdgeEditor.prototype.redraw = function() {
   445 Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
   336     var _coords = this.edge_controller.edge_paper_coords,
   446     var _coords = this.edge_controller.edge_paper_coords,
   337         _element = this.edge_controller._element,
   447         _element = this.edge_controller._element,
   338         _css = Rkns.Renderers.Paper__Utils.drawEditBox(_coords, this.editor_block, 250, 200);
   448         _css = Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 200);
   339     this.editor_$
   449     this.editor_$
   340         .html(this.template({
   450         .html(this.template({
   341             edge: _element,
   451             edge: _element,
   342             l10n: this._project.l10n
   452             l10n: this._project.l10n
   343         }))
   453         }))
   361         _this.edge_controller.redraw();
   471         _this.edge_controller.redraw();
   362         paper.view.draw();
   472         paper.view.draw();
   363     });
   473     });
   364 }
   474 }
   365 
   475 
   366 Rkns.Renderers.Paper__Controllers.EdgeEditor.prototype.destroy = function() {
   476 Rkns.Renderer.EdgeEditor.prototype.destroy = function() {
   367     this.editor_block.remove();
   477     this.editor_block.remove();
   368     this.editor_$.detach();
   478     this.editor_$.detach();
   369 }
   479 }
   370 
   480 
   371 /* */
   481 /* */
   372 
   482 
   373 Rkns.Renderers.Paper.prototype._init = function() {
   483 Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
       
   484 
       
   485 Rkns.Renderer.NodeEditButton.prototype._init = function() {
       
   486     this._renderer.node_layer.activate();
       
   487     this.type = "node-edit-button";
       
   488     this.sector = Rkns.Renderer.Utils.sector(1 + Rkns._NODE_RADIUS, 3 * Rkns._NODE_RADIUS, - 90, 30, 2, 'img/edit.png');
       
   489     this.sector.group.visible = false;
       
   490     this.sector.group.opacity = .5;
       
   491     this.sector.circle.__controller = this;
       
   492     this.sector.delta = this.sector.group.position;
       
   493 }
       
   494 
       
   495 Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
       
   496     this.sector.group.position = this.sector.delta.add(_pos);
       
   497 }
       
   498 
       
   499 Rkns.Renderer.NodeEditButton.prototype.show = function() {
       
   500     this.sector.group.visible = true;
       
   501 }
       
   502 
       
   503 Rkns.Renderer.NodeEditButton.prototype.hide = function() {
       
   504     this.sector.group.visible = false;
       
   505 }
       
   506 
       
   507 Rkns.Renderer.NodeEditButton.prototype.select = function() {
       
   508     this.sector.group.opacity = .8;
       
   509 }
       
   510 
       
   511 Rkns.Renderer.NodeEditButton.prototype.unselect = function() {
       
   512     this.sector.group.opacity = .5;
       
   513     this.hide();
       
   514     this.node_controller.remove_button.hide();
       
   515 }
       
   516 
       
   517 Rkns.Renderer.NodeEditButton.prototype.mouseup = function() {
       
   518     if (!this._renderer.is_dragging) {
       
   519         this.node_controller.mouseup();
       
   520     }
       
   521 }
       
   522 
       
   523 Rkns.Renderer.NodeEditButton.prototype.destroy = function() {
       
   524     this.sector.group.remove();
       
   525 }
       
   526 
       
   527 /* */
       
   528 
       
   529 Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
       
   530 
       
   531 Rkns.Renderer.NodeRemoveButton.prototype._init = function() {
       
   532     this._renderer.node_layer.activate();
       
   533     this.type = "node-remove-button";
       
   534     this.sector = Rkns.Renderer.Utils.sector(1 + Rkns._NODE_RADIUS, 3 * Rkns._NODE_RADIUS, -210, -90, 2, 'img/remove.png');
       
   535     this.sector.group.visible = false;
       
   536     this.sector.group.opacity = .5;
       
   537     this.sector.circle.__controller = this;
       
   538     this.sector.delta = this.sector.group.position;
       
   539 }
       
   540 
       
   541 Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
       
   542     this.sector.group.position = this.sector.delta.add(_pos);
       
   543 }
       
   544 
       
   545 Rkns.Renderer.NodeRemoveButton.prototype.show = function() {
       
   546     this.sector.group.visible = true;
       
   547 }
       
   548 
       
   549 Rkns.Renderer.NodeRemoveButton.prototype.hide = function() {
       
   550     this.sector.group.visible = false;
       
   551 }
       
   552 
       
   553 Rkns.Renderer.NodeRemoveButton.prototype.select = function() {
       
   554     this.sector.group.opacity = .8;
       
   555 }
       
   556 
       
   557 Rkns.Renderer.NodeRemoveButton.prototype.unselect = function() {
       
   558     this.sector.group.opacity = .5;
       
   559     this.hide();
       
   560     this.node_controller.edit_button.hide();
       
   561 }
       
   562 
       
   563 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
       
   564     this._renderer._project.removeNode(this.node_controller._element, Rkns._RENDER_AND_SAVE)
       
   565 }
       
   566 
       
   567 Rkns.Renderer.NodeRemoveButton.prototype.destroy = function() {
       
   568     this.sector.group.remove();
       
   569 }
       
   570 
       
   571 /* */
       
   572 
       
   573 Rkns.Renderer.Scene = function(_project) {
       
   574     this._project = _project;
   374     this._MARGIN_X = 80;
   575     this._MARGIN_X = 80;
   375     this._MARGIN_Y = 50;
   576     this._MARGIN_Y = 50;
   376     var _canvas_id = this._project._opts.canvas_id;
   577     var _canvas_id = this._project._opts.canvas_id;
   377     this.$ = Rkns.$("#"+_canvas_id)
   578     this.$ = Rkns.$("#"+_canvas_id)
   378     paper.setup(document.getElementById(_canvas_id));
   579     paper.setup(document.getElementById(_canvas_id));
   409         _this.offset = _this.offset.add(_event.delta.divide(2));
   610         _this.offset = _this.offset.add(_event.delta.divide(2));
   410         _this.redraw();
   611         _this.redraw();
   411     }
   612     }
   412 }
   613 }
   413 
   614 
   414 Rkns.Renderers.Paper.prototype.toPaperCoords = function(_point) {
   615 Rkns.Renderer.Scene.prototype.toPaperCoords = function(_point) {
   415     return _point.multiply(this.scale).add(this.offset);
   616     return _point.multiply(this.scale).add(this.offset);
   416 }
   617 }
   417 
   618 
   418 
   619 
   419 Rkns.Renderers.Paper.prototype.toModelCoords = function(_point) {
   620 Rkns.Renderer.Scene.prototype.toModelCoords = function(_point) {
   420     return _point.subtract(this.offset).divide(this.scale);
   621     return _point.subtract(this.offset).divide(this.scale);
   421 }
   622 }
   422 
   623 
   423 Rkns.Renderers.Paper.prototype.draw = function() {
   624 Rkns.Renderer.Scene.prototype.draw = function() {
   424     var _this = this,
   625     var _this = this,
   425         _xx = this._project.nodes.map(function(_node) { return _node.position.x }),
   626         _xx = this._project.nodes.map(function(_node) { return _node.position.x }),
   426         _yy = this._project.nodes.map(function(_node) { return _node.position.y }),
   627         _yy = this._project.nodes.map(function(_node) { return _node.position.y }),
   427         _minx = Math.min.apply(Math, _xx),
   628         _minx = Math.min.apply(Math, _xx),
   428         _miny = Math.min.apply(Math, _yy),
   629         _miny = Math.min.apply(Math, _yy),
   439     });
   640     });
   440     
   641     
   441     this.redraw();
   642     this.redraw();
   442 }
   643 }
   443 
   644 
   444 Rkns.Renderers.Paper.prototype.addController = function(_type, _controller) {
   645 Rkns.Renderer.Scene.prototype.addController = function(_type, _controller) {
   445     var _el = new Rkns.Renderers.Paper__Controllers[_type](this, _controller);
   646     var _el = new Rkns.Renderer[_type](this, _controller);
   446     this.controllers.push(_el);
   647     this.controllers.push(_el);
   447     return _el;
   648     return _el;
   448 }
   649 }
   449 
   650 
   450 Rkns.Renderers.Paper.prototype.removeController = function(_controller) {
   651 Rkns.Renderer.Scene.prototype.removeController = function(_controller) {
   451     _controller.destroy();
   652     _controller.destroy();
   452     this.controllers.removeId(_controller);
   653     this.controllers.removeId(_controller.id);
   453 }
   654 }
   454 
   655 
   455 Rkns.Renderers.Paper.prototype.removeControllersOfType = function(_type) {
   656 Rkns.Renderer.Scene.prototype.removeControllersOfType = function(_type) {
   456     var _controllers = this.controllers.filter(function(_ctrl) {
   657     var _controllers = this.controllers.filter(function(_ctrl) {
   457             return _ctrl.type == _type;
   658             return _ctrl.type == _type;
   458         }),
   659         }),
   459         _this = this;
   660         _this = this;
   460     _controllers.forEach(function(_ctrl) {
   661     _controllers.forEach(function(_ctrl) {
   461         _this.removeController(_ctrl);
   662         _this.removeController(_ctrl);
   462     });
   663     });
   463 }
   664 }
   464 
   665 
   465 Rkns.Renderers.Paper.prototype.redraw = function() {
   666 Rkns.Renderer.Scene.prototype.redraw = function() {
   466     this.controllers.forEach(function(_controller) {
   667     this.controllers.forEach(function(_controller) {
   467         _controller.redraw();
   668         _controller.redraw();
   468     });
   669     });
   469     paper.view.draw();
   670     paper.view.draw();
   470 }
   671 }
   471 
   672 
   472 Rkns.Renderers.Paper.prototype.onMouseMove = function(_event) {
   673 Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) {
   473     var _hitResult = paper.project.hitTest(_event.point);
   674     var _hitResult = paper.project.hitTest(_event.point);
   474     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
   675     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
       
   676         var _newTarget = _hitResult.item.__controller;
   475         if (this.selected_target !== _hitResult.item.__controller) {
   677         if (this.selected_target !== _hitResult.item.__controller) {
   476             if (this.selected_target) {
   678             if (this.selected_target) {
   477                 this.selected_target.unselect();
   679                 this.selected_target.unselect(_newTarget);
   478             }
   680             }
   479             this.selected_target = _hitResult.item.__controller;
   681             _newTarget.select(this.selected_target);
   480             this.selected_target.select();
   682             this.selected_target = _newTarget;
   481         }
   683         }
   482     } else {
   684     } else {
   483         if (this.selected_target) {
   685         if (this.selected_target) {
   484             this.selected_target.unselect();
   686             this.selected_target.unselect(null);
   485         }
   687         }
   486         this.selected_target = null;
   688         this.selected_target = null;
   487     }
   689     }
   488 }
   690 }
   489 
   691 
   490 Rkns.Renderers.Paper.prototype.onMouseDown = function(_event) {
   692 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
   491     this.is_dragging = false;
   693     this.is_dragging = false;
   492     var _hitResult = paper.project.hitTest(_event.point);
   694     var _hitResult = paper.project.hitTest(_event.point);
   493     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
   695     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
   494         this.click_target = _hitResult.item.__controller;
   696         this.click_target = _hitResult.item.__controller;
   495         if (this.click_target.type === "node" && _hitResult.type === "stroke") {
   697         if (this.click_target.type === "node" && _hitResult.type === "stroke") {
   496             var _tmpEdge = this.addController("TempEdge",{});
   698             var _tmpEdge = this.addController("TempEdge",{});
   497             _tmpEdge.end_pos = _event.point;
   699             _tmpEdge.end_pos = _event.point;
   498             _tmpEdge.from_node_controller = this.click_target;
   700             _tmpEdge.from_controller = this.click_target;
   499             _tmpEdge.redraw();
   701             _tmpEdge.redraw();
   500             this.click_target = _tmpEdge;
   702             this.click_target = _tmpEdge;
   501         }
   703         }
   502     } else {
   704     } else {
   503         this.click_target = null;
   705         this.click_target = null;
   504     }
   706     }
   505 }
   707 }
   506 
   708 
   507 Rkns.Renderers.Paper.prototype.onMouseDrag = function(_event) {
   709 Rkns.Renderer.Scene.prototype.onMouseDrag = function(_event) {
   508     this.is_dragging = true;
   710     this.is_dragging = true;
   509     if (this.click_target && typeof this.click_target.paperShift === "function") {
   711     if (this.click_target && typeof this.click_target.paperShift === "function") {
   510         this.click_target.paperShift(_event.delta);
   712         this.click_target.paperShift(_event.delta);
   511     } else {
   713     } else {
   512         this.offset = this.offset.add(_event.delta);
   714         this.offset = this.offset.add(_event.delta);
   513         this.redraw();
   715         this.redraw();
   514     }
   716     }
   515 }
   717 }
   516 
   718 
   517 Rkns.Renderers.Paper.prototype.onMouseUp = function(_event) {
   719 Rkns.Renderer.Scene.prototype.onMouseUp = function(_event) {
   518     if (this.click_target) {
   720     if (this.click_target) {
   519         switch (this.click_target.type) {
   721         this.click_target.mouseup(_event);
   520             case "node":
       
   521                 if (!this.is_dragging) {
       
   522                     this.removeControllersOfType("editor");
       
   523                     var _editor = this.addController("NodeEditor",{});
       
   524                     _editor.node_controller = this.click_target;
       
   525                     _editor.redraw();
       
   526                 }
       
   527             break;
       
   528             case "edge":
       
   529                 if (!this.is_dragging) {
       
   530                     this.removeControllersOfType("editor");
       
   531                     var _editor = this.addController("EdgeEditor",{});
       
   532                     _editor.edge_controller = this.click_target;
       
   533                     _editor.redraw();
       
   534                 }
       
   535             break;
       
   536             case "temp-edge":
       
   537                 this.click_target.finishEdge(_event);
       
   538             break;
       
   539         }
       
   540     }
   722     }
   541     this.is_dragging = false;
   723     this.is_dragging = false;
   542     this.click_target = null;
   724     this.click_target = null;
   543 }
   725 }
   544 
   726 
   545 Rkns.Renderers.Paper.prototype.onScroll = function(_event, _scrolldelta) {
   727 Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) {
   546     this.totalScroll += _scrolldelta;
   728     this.totalScroll += _scrolldelta;
   547     if (Math.abs(this.totalScroll) >= 1) {
   729     if (Math.abs(this.totalScroll) >= 1) {
   548         var _off = this.$.offset(),
   730         var _off = this.$.offset(),
   549             _delta = new paper.Point([
   731             _delta = new paper.Point([
   550                 _event.pageX - _off.left,
   732                 _event.pageX - _off.left,
   560         this.totalScroll = 0;
   742         this.totalScroll = 0;
   561         this.redraw();
   743         this.redraw();
   562     }
   744     }
   563 }
   745 }
   564 
   746 
   565 Rkns.Renderers.Paper.prototype.onDoubleClick = function(_event) {
   747 Rkns.Renderer.Scene.prototype.onDoubleClick = function(_event) {
   566     var _off = this.$.offset(),
   748     var _off = this.$.offset(),
   567         _point = new paper.Point([
   749         _point = new paper.Point([
   568             _event.pageX - _off.left,
   750             _event.pageX - _off.left,
   569             _event.pageY - _off.top
   751             _event.pageY - _off.top
   570         ]);
   752         ]);