src/js/libs/renkan-publish.js
changeset 955 5055aa35340f
parent 950 b7e236e4ec1c
equal deleted inserted replaced
954:71a8438be150 955:5055aa35340f
    25 Rkns._ = _;
    25 Rkns._ = _;
    26 
    26 
    27 Rkns.i18n = {
    27 Rkns.i18n = {
    28     en: {
    28     en: {
    29         zoom_in: "Zoom In",
    29         zoom_in: "Zoom In",
    30         zoom_out: "Zoom Out"
    30         zoom_out: "Zoom Out",
       
    31         see_in_project: 'See also <b>"{node}"</b> in <b>"{project}"</b>'
    31     }
    32     }
    32 }
    33 }
    33 
    34 
    34 Rkns.Utils = {
    35 Rkns.Utils = {
    35     inherit : function(_baseClass) {
    36     inherit : function(_baseClass) {
    55 };
    56 };
    56 
    57 
    57 Rkns.Models.RenkanModel = Backbone.RelationalModel.extend({
    58 Rkns.Models.RenkanModel = Backbone.RelationalModel.extend({
    58     idAttribute : "_id",
    59     idAttribute : "_id",
    59     constructor: function(options) {
    60     constructor: function(options) {
    60         
    61 
    61         if (typeof options !== "undefined") {
    62         if (typeof options !== "undefined") {
    62             options._id = options._id || options.id || Rkns.Models.getUID(this);
    63             options._id = options._id || options.id || Rkns.Models.getUID(this);
    63             options.title = options.title || "(untitled " + this.type + ")";
    64             options.title = options.title || "(untitled " + this.type + ")";
    64             options.description = options.description || "";
    65             options.description = options.description || "";
    65             options.uri = options.uri || "";
    66             options.uri = options.uri || "";
    66             
    67 
    67             if(typeof this.prepare === "function") {
    68             if(typeof this.prepare === "function") {
    68                 options = this.prepare(options);
    69                 options = this.prepare(options);
    69             }
    70             }
    70         }
    71         }
    71         Backbone.RelationalModel.prototype.constructor.call(this, options);
    72         Backbone.RelationalModel.prototype.constructor.call(this, options);
   123             id: this.get("_id"),
   124             id: this.get("_id"),
   124             title: this.get("title"),
   125             title: this.get("title"),
   125             uri: this.get("uri"),
   126             uri: this.get("uri"),
   126             description: this.get("description"),
   127             description: this.get("description"),
   127             position: this.get("position"),
   128             position: this.get("position"),
       
   129             image: this.get("image"),
   128             created_by: this.get("created_by").get("_id")
   130             created_by: this.get("created_by").get("_id")
   129         }
   131         }
   130     },
   132     },
   131 });
   133 });
   132 
   134 
   261         _opts.container = "renkan";
   263         _opts.container = "renkan";
   262     }
   264     }
   263     if (typeof _opts.search !== "object" || !_opts.search) {
   265     if (typeof _opts.search !== "object" || !_opts.search) {
   264         _opts.search = [];
   266         _opts.search = [];
   265     }
   267     }
   266     this.project = new Rkns.Models.Project();
   268     this.projects = [];
   267     this.l10n = Rkns.i18n[_opts.language];
   269     this.l10n = Rkns.i18n[_opts.language];
   268     this.$ = Rkns.$("#" + _opts.container);
   270     this.$ = Rkns.$("#" + _opts.container);
   269     this.$.html(this.template());
   271     this.$.html(this.template());
   270     this.renderer = new Rkns.Renderer.Scene(this);
   272     this.uris = {};
   271 }
   273     this.active_project = null;
       
   274     this.renderer = null;
       
   275 }
       
   276 
   272 Rkns.Renkan.prototype.template = Rkns._.template(
   277 Rkns.Renkan.prototype.template = Rkns._.template(
   273     '<div class="Rk-Render Rk-Render-Full"></div>'
   278     '<div class="Rk-Render"></div><ul class="Rk-Project-List"></ul>'
   274 );
   279 );
   275 
   280 
   276 Rkns.jsonImport = function(_renkan, _opts) {
   281 Rkns.Renkan.prototype.addProject = function(_opts) {
   277     var _proj = _renkan.project;
   282     var _proj = new Rkns.Models.Project(),
       
   283         _li = Rkns.$("<li>").addClass("Rk-Project").text("Untitled #" + (1+this.projects.length));
       
   284     this.$.find(".Rk-Project-List").append(_li);
       
   285     Rkns.loadJson(_proj, _opts);
       
   286     var _this = this;
       
   287     _li.click(function() {
       
   288         _this.renderProject(_proj);
       
   289     });
       
   290     _proj.on("change:title", function() {
       
   291         _li.html(_proj.get("title"));
       
   292     });
       
   293     _proj.on("select", function() {
       
   294         _this.$.find(".Rk-Project").removeClass("active");
       
   295         _li.addClass("active");
       
   296     });
       
   297     _proj.on("add:nodes", function(_node) {
       
   298         var _uri = _node.get("uri");
       
   299         if (_uri) {
       
   300             if (typeof _this.uris[_uri] === "undefined") {
       
   301                 _this.uris[_uri] = [];
       
   302             }
       
   303             _this.uris[_uri].push(_node);
       
   304         }
       
   305     });
       
   306     this.projects.push(_proj);
       
   307     return _proj;
       
   308 }
       
   309 
       
   310 Rkns.Renkan.prototype.renderProject = function(_project) {
       
   311     if (_project) {
       
   312         if (this.renderer) {
       
   313             this.renderer.destroy();
       
   314         }
       
   315         this.active_project = _project;
       
   316         this.renderer = new Rkns.Renderer.Scene(this, _project);
       
   317         this.renderer.autoScale();
       
   318         _project.trigger("select");
       
   319     }
       
   320 }
       
   321 
       
   322 Rkns.Renkan.prototype.renderProjectAt = function(_index) {
       
   323     this.renderProject(this.projects[_index]);
       
   324 }
       
   325 
       
   326 Rkns.loadJson = function(_proj, _opts) {
   278     if (typeof _opts.http_method == "undefined") {
   327     if (typeof _opts.http_method == "undefined") {
   279         _opts.http_method = 'PUT';
   328         _opts.http_method = 'PUT';
   280     }
   329     }
   281     var _load = function() {
   330     var _load = function() {
   282         Rkns.$.getJSON(_opts.url, function(_data) {
   331         Rkns.$.getJSON(_opts.url, function(_data) {
   283             _proj.set(_data);
   332             _proj.set(_data);
   284             _renkan.renderer.autoScale();
   333             if (typeof _opts.callback === "function") {
       
   334                 _opts.callback(_proj);
       
   335             }
   285         });
   336         });
   286     }
   337     }
   287     _load();
   338     _load();
   288 }
   339 }
   289 
   340 
   290 Rkns.Renderer = {
   341 Rkns.Renderer = {
   291     _MARGIN_X: 80,
   342     _MARGIN_X: 80,
   292     _MARGIN_Y: 50,
   343     _MARGIN_Y: 50,
   293     _MIN_DRAG_DISTANCE: 2,
   344     _MIN_DRAG_DISTANCE: 2,
   294     _NODE_RADIUS: 15,
   345     _NODE_RADIUS: 20,
   295     _NODE_FONT_SIZE: 10,
   346     _NODE_FONT_SIZE: 10,
   296     _EDGE_FONT_SIZE: 9,
   347     _EDGE_FONT_SIZE: 9,
   297     _NODE_MAX_CHAR: 30,
   348     _NODE_MAX_CHAR: 30,
   298     _EDGE_MAX_CHAR: 20,
   349     _EDGE_MAX_CHAR: 20,
   299     _ARROW_LENGTH: 16,
   350     _ARROW_LENGTH: 16,
   356 }
   407 }
   357 
   408 
   358 Rkns.Renderer._BaseRepresentation = function(_renderer, _model) {
   409 Rkns.Renderer._BaseRepresentation = function(_renderer, _model) {
   359     if (typeof _renderer !== "undefined") {
   410     if (typeof _renderer !== "undefined") {
   360         this.renderer = _renderer;
   411         this.renderer = _renderer;
   361         this.project = _renderer.renkan.project;
   412         this.project = _renderer.project;
   362         this.model = _model;
   413         this.model = _model;
   363         if (_model) {
   414         if (this.model) {
   364             var _this = this;
   415             var _this = this;
   365             _model.on("select", function() {
   416             this._selectBinding = function() {
   366                 _this.select();
   417                 _this.select();
   367             });
   418             };
   368             _model.on("unselect", function() {
   419             this._unselectBinding = function() {
   369                 _this.unselect();
   420                 _this.unselect();
   370             });
   421             }
   371         }
   422             this._changeBinding = function() {
   372     }
   423                 _this.redraw();
       
   424             }
       
   425             this._removeBinding = function() {
       
   426                 _renderer.removeRepresentation(_this);
       
   427                 _renderer.redraw();
       
   428             }
       
   429             this.model.on("change", this._changeBinding );
       
   430             this.model.on("remove", this._removeBinding );
       
   431             this.model.on("select", this._selectBinding );
       
   432             this.model.on("unselect", this._unselectBinding );
       
   433         }
       
   434     }
       
   435 }
       
   436 
       
   437 Rkns.Renderer._BaseRepresentation.prototype.super = function(_func) {
       
   438     Rkns.Renderer._BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1));
   373 }
   439 }
   374 
   440 
   375 Rkns.Renderer._BaseRepresentation.prototype.select = function() {}
   441 Rkns.Renderer._BaseRepresentation.prototype.select = function() {}
   376 
   442 
   377 Rkns.Renderer._BaseRepresentation.prototype.unselect = function() {}
   443 Rkns.Renderer._BaseRepresentation.prototype.unselect = function() {}
   378 
   444 
   379 Rkns.Renderer._BaseRepresentation.prototype.highlight = function() {}
       
   380 
       
   381 Rkns.Renderer._BaseRepresentation.prototype.unhighlight = function() {}
       
   382 
       
   383 Rkns.Renderer._BaseRepresentation.prototype.mouseup = function() {}
   445 Rkns.Renderer._BaseRepresentation.prototype.mouseup = function() {}
   384 
   446 
   385 Rkns.Renderer._BaseRepresentation.prototype.destroy = function() {}
   447 Rkns.Renderer._BaseRepresentation.prototype.destroy = function() {
       
   448     if (this.model) {
       
   449         this.model.off("change", this._changeBinding );
       
   450         this.model.off("remove", this._removeBinding );
       
   451         this.model.off("select", this._selectBinding);
       
   452         this.model.off("unselect", this._unselectBinding);
       
   453     }
       
   454 }
   386 
   455 
   387 Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   456 Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   388 
   457 
   389 Rkns.Renderer.Node.prototype._init = function() {
   458 Rkns.Renderer.Node.prototype._init = function() {
   390     this.renderer.node_layer.activate();
   459     this.renderer.node_layer.activate();
   406     this.paper_coords = this.renderer.toPaperCoords(this.model_coords);
   475     this.paper_coords = this.renderer.toPaperCoords(this.model_coords);
   407     this.circle.position = this.paper_coords;
   476     this.circle.position = this.paper_coords;
   408     this.title.content = Rkns.Renderer.Utils.shortenText(this.model.get("title"), Rkns.Renderer._NODE_MAX_CHAR);
   477     this.title.content = Rkns.Renderer.Utils.shortenText(this.model.get("title"), Rkns.Renderer._NODE_MAX_CHAR);
   409     this.title.position = this.paper_coords.add([0, 2 * Rkns.Renderer._NODE_RADIUS]);
   478     this.title.position = this.paper_coords.add([0, 2 * Rkns.Renderer._NODE_RADIUS]);
   410     this.circle.strokeColor = this.model.get("created_by").get("color");
   479     this.circle.strokeColor = this.model.get("created_by").get("color");
       
   480     var _img = this.model.get("image");
       
   481     if (_img && _img !== this.img) {
       
   482         var _image = new Image(),
       
   483             _this = this;
       
   484         _image.onload = function() {
       
   485             if (_this.node_image) {
       
   486                 _this.node_image.remove();
       
   487             }
       
   488             _this.renderer.node_layer.activate();
       
   489             var _ratio = Math.min(1, 2 * Rkns.Renderer._NODE_RADIUS / _image.width, 2 * Rkns.Renderer._NODE_RADIUS / _image.height );
       
   490             var _raster = new paper.Raster(_image);
       
   491             var _clip = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS);
       
   492             _raster.scale(_ratio);
       
   493             _this.node_image = new paper.Group(_clip, _raster);
       
   494             _this.node_image.opacity = _this.selected ? .5 : .9;
       
   495             /* This is a workaround to allow clipping at group level */
       
   496             _this.node_image.clipped = true;
       
   497             _this.node_image.position = _this.paper_coords;
       
   498             _this.node_image.__representation = _this;
       
   499             paper.view.draw();
       
   500         }
       
   501         _image.src = _img;
       
   502     }
       
   503     this.img = _img;
       
   504     if (this.node_image) {
       
   505         if (!this.img) {
       
   506             this.node_image.remove();
       
   507             delete this.node_image;
       
   508         } else {
       
   509             this.node_image.position = this.paper_coords;
       
   510         }
       
   511     }
   411 }
   512 }
   412 
   513 
   413 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   514 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
   414     this.paper_coords = this.paper_coords.add(_delta);
   515     this.paper_coords = this.paper_coords.add(_delta);
   415     this.model_coords = this.renderer.toModelCoords(this.paper_coords);
   516     this.model_coords = this.renderer.toModelCoords(this.paper_coords);
   418 
   519 
   419 Rkns.Renderer.Node.prototype.openTooltip = function() {
   520 Rkns.Renderer.Node.prototype.openTooltip = function() {
   420     this.renderer.removeRepresentationsOfType("tooltip");
   521     this.renderer.removeRepresentationsOfType("tooltip");
   421     var _tooltip = this.renderer.addRepresentation("NodeTooltip",null);
   522     var _tooltip = this.renderer.addRepresentation("NodeTooltip",null);
   422     _tooltip.node_representation = this;
   523     _tooltip.node_representation = this;
   423     _tooltip.redraw();
   524     _tooltip.draw();
   424 }
   525 }
   425 
   526 
   426 Rkns.Renderer.Node.prototype.select = function() {
   527 Rkns.Renderer.Node.prototype.select = function() {
       
   528     this.selected = true;
   427     this.circle.strokeWidth = 3;
   529     this.circle.strokeWidth = 3;
   428     this.circle.fillColor = "#ffffc0";
   530     this.openTooltip();
       
   531     this.circle.fillColor = "#ffff80";
       
   532     if (this.node_image) {
       
   533         this.node_image.opacity = .5;
       
   534     }
   429     paper.view.draw();
   535     paper.view.draw();
   430 }
   536 }
   431 
   537 
   432 Rkns.Renderer.Node.prototype.unselect = function() {
   538 Rkns.Renderer.Node.prototype.unselect = function() {
       
   539     this.selected = false;
   433     this.circle.strokeWidth = 1;
   540     this.circle.strokeWidth = 1;
   434     this.circle.fillColor = "#ffffff";
   541     this.circle.fillColor = "#ffffff";
       
   542     if (this.node_image) {
       
   543         this.node_image.opacity = .9;
       
   544     }
   435     paper.view.draw();
   545     paper.view.draw();
   436 }
   546 }
   437 
   547 
   438 Rkns.Renderer.Node.prototype.mouseup = function(_event) {
   548 Rkns.Renderer.Node.prototype.mouseup = function(_event) {
   439 }
   549 }
   440 
   550 
   441 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   551 Rkns.Renderer.Node.prototype.destroy = function(_event) {
       
   552     this.super("destroy");
   442     this.circle.remove();
   553     this.circle.remove();
   443     this.title.remove();
   554     this.title.remove();
       
   555     if (this.node_image) {
       
   556         this.node_image.remove();
       
   557     }
   444 }
   558 }
   445 
   559 
   446 /* */
   560 /* */
   447 
   561 
   448 Rkns.Renderer.Edge = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   562 Rkns.Renderer.Edge = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   508 
   622 
   509 Rkns.Renderer.Edge.prototype.openTooltip = function() {
   623 Rkns.Renderer.Edge.prototype.openTooltip = function() {
   510     this.renderer.removeRepresentationsOfType("tooltip");
   624     this.renderer.removeRepresentationsOfType("tooltip");
   511     var _tooltip = this.renderer.addRepresentation("EdgeTooltip",null);
   625     var _tooltip = this.renderer.addRepresentation("EdgeTooltip",null);
   512     _tooltip.edge_representation = this;
   626     _tooltip.edge_representation = this;
   513     _tooltip.redraw();
   627     _tooltip.draw();
   514 }
   628 }
   515 
   629 
   516 Rkns.Renderer.Edge.prototype.select = function() {
   630 Rkns.Renderer.Edge.prototype.select = function() {
   517     this.line.strokeWidth = 3;
   631     this.line.strokeWidth = 3;
   518     this.openTooltip();
   632     this.openTooltip();
   532     this.to_representation.paperShift(_delta);
   646     this.to_representation.paperShift(_delta);
   533     this.renderer.redraw();
   647     this.renderer.redraw();
   534 }
   648 }
   535 
   649 
   536 Rkns.Renderer.Edge.prototype.destroy = function() {
   650 Rkns.Renderer.Edge.prototype.destroy = function() {
       
   651     this.super("destroy");
   537     this.line.remove();
   652     this.line.remove();
   538     this.arrow.remove();
   653     this.arrow.remove();
   539     this.text.remove();
   654     this.text.remove();
   540     var _this = this;
   655     var _this = this;
   541     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   656     this.bundle.edges = Rkns._(this.bundle.edges).reject(function(_edge) {
   566         .hide();
   681         .hide();
   567 }
   682 }
   568 
   683 
   569 Rkns.Renderer.NodeTooltip.prototype.template = Rkns._.template(
   684 Rkns.Renderer.NodeTooltip.prototype.template = Rkns._.template(
   570     '<h2><span class="Rk-CloseX">&times;</span><%=a%></h2>'
   685     '<h2><span class="Rk-CloseX">&times;</span><%=a%></h2>'
   571     + '<p><%=description%></p>'
   686     + '<p><%-description%></p>'
       
   687     + '<ul class="Rk-Related-List"></ul>'
   572 );
   688 );
   573 
   689 
   574 Rkns.Renderer.NodeTooltip.prototype.redraw = function() {
   690 Rkns.Renderer.NodeTooltip.prototype.draw = function() {
   575     var _coords = this.node_representation.paper_coords,
   691     var _model = this.node_representation.model,
   576         _model = this.node_representation.model,
       
   577         _title = _model.get("title"),
   692         _title = _model.get("title"),
   578         _uri = _model.get("uri");
   693         _uri = _model.get("uri");
   579     this.tooltip_$
   694     this.tooltip_$
   580         .html(this.template({
   695         .html(this.template({
   581             a: (_uri ? '<a href="' + _uri + '" target="_blank">' : '' ) + _title + (_uri ? '</a>' : '' ),
   696             a: (_uri ? '<a href="' + _uri + '" target="_blank">' : '' ) + _title + (_uri ? '</a>' : '' ),
   582             description: _model.get("description").replace(/(\n|\r|\r\n)/mg,' ').substr(0,180).replace(/(^.{150,179})[\s].+$/m,'$1&hellip;')
   697             description: _model.get("description").replace(/(\n|\r|\r\n)/mg,' ').substr(0,180).replace(/(^.{150,179})[\s].+$/m,'$1&hellip;')
   583         }))
   698         }))
   584         .show();
   699     var _this = this,
   585     Rkns.Renderer.Utils.drawTooltip(_coords, this.tooltip_block, 250, 15, this.tooltip_$);
   700         _renkan = this.renderer.renkan,
   586     var _this = this;
   701         _uris = _renkan.uris[_uri];
       
   702     Rkns._(_uris).each(function(_othernode) {
       
   703         if (_othernode !== _model && _othernode.get("project") !== _this.project) {
       
   704             var _otherproj = _othernode.get("project"),
       
   705                 _nodetitle = _othernode.get("title") || "Untitled node"
       
   706                 _projtitle = _otherproj.get("title") || "Untitled node",
       
   707                 _html = _renkan.l10n.see_in_project.replace('{node}',Rkns._.escape(_nodetitle)).replace('{project}',Rkns._.escape(_projtitle)),
       
   708                 _li = Rkns.$("<li>").addClass("Rk-Related").html(_html);
       
   709             _li.click(function() {
       
   710                 _renkan.renderProject(_otherproj);
       
   711                 Rkns._.defer(function() {
       
   712                     _othernode.trigger("select");
       
   713                 });
       
   714             });
       
   715             _this.tooltip_$.append(_li);
       
   716         }
       
   717     });
   587     this.tooltip_$.find(".Rk-CloseX").click(function() {
   718     this.tooltip_$.find(".Rk-CloseX").click(function() {
   588         _this.renderer.removeRepresentation(_this);
   719         _this.renderer.removeRepresentation(_this);
   589         paper.view.draw();
   720         paper.view.draw();
   590     });
   721     });
   591     this.tooltip_$.find("input, textarea").bind("keyup change", function() {
   722     this.redraw();
   592         _this.tooltip_$.find(".Rk-Edit-Goto").attr("href",_this.tooltip_$.find(".Rk-Edit-URI").val());
   723 }
   593     });
   724 
   594     paper.view.draw();
   725 Rkns.Renderer.NodeTooltip.prototype.redraw = function() {
       
   726     var _coords = this.node_representation.paper_coords;
       
   727     Rkns.Renderer.Utils.drawTooltip(_coords, this.tooltip_block, 250, 15, this.tooltip_$);
       
   728     this.tooltip_$.show();
   595 }
   729 }
   596 
   730 
   597 Rkns.Renderer.NodeTooltip.prototype.destroy = function() {
   731 Rkns.Renderer.NodeTooltip.prototype.destroy = function() {
   598     this.tooltip_block.remove();
   732     this.tooltip_block.remove();
   599     this.tooltip_$.detach();
   733     this.tooltip_$.detach();
   622         .hide();
   756         .hide();
   623 }
   757 }
   624 
   758 
   625 Rkns.Renderer.EdgeTooltip.prototype.template = Rkns._.template(
   759 Rkns.Renderer.EdgeTooltip.prototype.template = Rkns._.template(
   626     '<h2><span class="Rk-CloseX">&times;</span><%=a%></h2>'
   760     '<h2><span class="Rk-CloseX">&times;</span><%=a%></h2>'
   627     + '<p><%=description%></p>'
   761     + '<p><%-description%></p>'
   628 );
   762 );
   629 
   763 
   630 Rkns.Renderer.EdgeTooltip.prototype.redraw = function() {
   764 Rkns.Renderer.EdgeTooltip.prototype.draw = function() {
   631     var _coords = this.edge_representation.paper_coords,
   765     var _model = this.edge_representation.model,
   632         _model = this.edge_representation.model,
       
   633         _title = _model.get("title"),
   766         _title = _model.get("title"),
   634         _uri = _model.get("uri");
   767         _uri = _model.get("uri");
   635     this.tooltip_$
   768     this.tooltip_$
   636         .html(this.template({
   769         .html(this.template({
   637             a: (_uri ? '<a href="' + _uri + '" target="_blank">' : '' ) + _title + (_uri ? '</a>' : '' ),
   770             a: (_uri ? '<a href="' + _uri + '" target="_blank">' : '' ) + _title + (_uri ? '</a>' : '' ),
   638             description: _model.get("description").replace(/(\n|\r|\r\n)/mg,' ').substr(0,180).replace(/(^.{150,179})[\s].+$/m,'$1&hellip;')
   771             description: _model.get("description").replace(/(\n|\r|\r\n)/mg,' ').substr(0,180).replace(/(^.{150,179})[\s].+$/m,'$1&hellip;')
   639         }))
   772         }));
   640         .show();
   773     this.redraw();
   641     Rkns.Renderer.Utils.drawTooltip(_coords, this.tooltip_block, 250, 5, this.tooltip_$);
       
   642     var _this = this;
   774     var _this = this;
   643     this.tooltip_$.find(".Rk-CloseX").click(function() {
   775     this.tooltip_$.find(".Rk-CloseX").click(function() {
   644         _this.renderer.removeRepresentation(_this);
   776         _this.renderer.removeRepresentation(_this);
   645         paper.view.draw();
   777         paper.view.draw();
   646     });
   778     });
       
   779 }
       
   780 
       
   781 Rkns.Renderer.EdgeTooltip.prototype.redraw = function() {
       
   782     var _coords = this.edge_representation.paper_coords;
       
   783     Rkns.Renderer.Utils.drawTooltip(_coords, this.tooltip_block, 250, 5, this.tooltip_$);
       
   784     this.tooltip_$.show();
   647     paper.view.draw();
   785     paper.view.draw();
   648 }
   786 }
   649 
   787 
   650 Rkns.Renderer.EdgeTooltip.prototype.destroy = function() {
   788 Rkns.Renderer.EdgeTooltip.prototype.destroy = function() {
   651     this.tooltip_block.remove();
   789     this.tooltip_block.remove();
   652     this.tooltip_$.detach();
   790     this.tooltip_$.detach();
   653 }
   791 }
   654 
   792 
   655 /* */
   793 /* */
   656 
   794 
   657 Rkns.Renderer.Scene = function(_renkan) {
   795 Rkns.Renderer.Scene = function(_renkan, _project) {
   658     this.renkan = _renkan;
   796     this.renkan = _renkan;
       
   797     this.project = _project;
   659     this.$ = Rkns.$(".Rk-Render");
   798     this.$ = Rkns.$(".Rk-Render");
   660     this.representations = [];
   799     this.representations = [];
   661     this.$.html(this.template({
   800     this.$.html(this.template({
   662         width: this.$.width(),
   801         width: this.$.width(),
   663         height: this.$.height(),
   802         height: this.$.height(),
   716     
   855     
   717     var _thRedraw = Rkns._.throttle(function() {
   856     var _thRedraw = Rkns._.throttle(function() {
   718         _this.redraw();
   857         _this.redraw();
   719     },50);
   858     },50);
   720     
   859     
   721     this.addRepresentations("Node", this.renkan.project.get("nodes"));
   860     this.addRepresentations("Node", this.project.get("nodes"));
   722     this.addRepresentations("Edge", this.renkan.project.get("edges"));
   861     this.addRepresentations("Edge", this.project.get("edges"));
   723     
   862     
   724     this.renkan.project.on("add:nodes", function(_node) {
   863     this._addNodesBinding = function(_node) {
   725         _this.addRepresentation("Node", _node);
   864         _this.addRepresentation("Node", _node);
   726         _thRedraw();
   865         _thRedraw();
   727     });
   866     }
   728     this.renkan.project.on("add:edges", function(_edge) {
   867     this._addEdgesBinding = function(_edge) {
   729         _this.addRepresentation("Edge", _edge);
   868         _this.addRepresentation("Edge", _edge);
   730         _thRedraw();
   869         _thRedraw();
   731     });
   870     }
   732     
   871     
       
   872     this.project.on("add:nodes", this._addNodesBinding );
       
   873     this.project.on("add:edges", this._addEdgesBinding );
   733     this.redraw();
   874     this.redraw();
   734 }
   875 }
   735 
   876 
   736 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
   877 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
   737     '<canvas class="Rk-Canvas" width="<%=width%>" height="<%=height%>"></canvas><div class="Rk-Editor">'
   878     '<canvas class="Rk-Canvas" width="<%-width%>" height="<%-height%>"></canvas><div class="Rk-Editor">'
   738     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
   879     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%-l10n.zoom_out%>"></div></div>'
   739     + '</div>'
   880     + '</div>'
   740 );
   881 );
   741 
   882 
   742 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
   883 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
   743     var _bundle = Rkns._(this.bundles).find(function(_bundle) {
   884     var _bundle = Rkns._(this.bundles).find(function(_bundle) {
   762     }
   903     }
   763     return _bundle;
   904     return _bundle;
   764 }
   905 }
   765 
   906 
   766 Rkns.Renderer.Scene.prototype.autoScale = function() {
   907 Rkns.Renderer.Scene.prototype.autoScale = function() {
   767     if (this.renkan.project.get("nodes").length) {
   908     if (this.project.get("nodes").length) {
   768         var _xx = this.renkan.project.get("nodes").map(function(_node) { return _node.get("position").x }),
   909         var _xx = this.project.get("nodes").map(function(_node) { return _node.get("position").x }),
   769             _yy = this.renkan.project.get("nodes").map(function(_node) { return _node.get("position").y }),
   910             _yy = this.project.get("nodes").map(function(_node) { return _node.get("position").y }),
   770             _minx = Math.min.apply(Math, _xx),
   911             _minx = Math.min.apply(Math, _xx),
   771             _miny = Math.min.apply(Math, _yy),
   912             _miny = Math.min.apply(Math, _yy),
   772             _maxx = Math.max.apply(Math, _xx),
   913             _maxx = Math.max.apply(Math, _xx),
   773             _maxy = Math.max.apply(Math, _yy);
   914             _maxy = Math.max.apply(Math, _yy);
   774         this.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));
   915         this.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));
   787 }
   928 }
   788 
   929 
   789 Rkns.Renderer.Scene.prototype.addRepresentation = function(_type, _model) {
   930 Rkns.Renderer.Scene.prototype.addRepresentation = function(_type, _model) {
   790     var _repr = new Rkns.Renderer[_type](this, _model);
   931     var _repr = new Rkns.Renderer[_type](this, _model);
   791     this.representations.push(_repr);
   932     this.representations.push(_repr);
   792     if (_model) {
       
   793         var _this = this;
       
   794         _model.on("change", function() {
       
   795             _repr.redraw();
       
   796         });
       
   797         _model.on("remove", function() {
       
   798             _this.removeRepresentation(_repr);
       
   799             _this.redraw();
       
   800         });
       
   801     }
       
   802     return _repr;
   933     return _repr;
   803 }
   934 }
   804 
   935 
   805 Rkns.Renderer.Scene.prototype.addRepresentations = function(_type, _collection) {
   936 Rkns.Renderer.Scene.prototype.addRepresentations = function(_type, _collection) {
   806     var _this = this;
   937     var _this = this;
   861         if (this.selected_target !== _newTarget && _newTarget.model) {
   992         if (this.selected_target !== _newTarget && _newTarget.model) {
   862             if (this.selected_target) {
   993             if (this.selected_target) {
   863                 this.selected_target.model.trigger("unselect");
   994                 this.selected_target.model.trigger("unselect");
   864             }
   995             }
   865             _newTarget.model.trigger("select");
   996             _newTarget.model.trigger("select");
   866             if (typeof _newTarget.openTooltip === "function") {
       
   867                 _newTarget.openTooltip();
       
   868             }
       
   869             this.selected_target = _newTarget;
   997             this.selected_target = _newTarget;
   870         }
   998         }
   871     } else {
   999     } else {
   872         if (!_hitResult) {
  1000         if (!_hitResult) {
   873             this.removeRepresentationsOfType("tooltip");
  1001             this.removeRepresentationsOfType("tooltip");
   936         }
  1064         }
   937         this.totalScroll = 0;
  1065         this.totalScroll = 0;
   938         this.redraw();
  1066         this.redraw();
   939     }
  1067     }
   940 }
  1068 }
       
  1069 
       
  1070 Rkns.Renderer.Scene.prototype.destroy = function() {
       
  1071     this.project.off("add:nodes", this._addNodesBinding );
       
  1072     this.project.off("add:edges", this._addEdgesBinding );
       
  1073     Rkns._(this.representations).each(function(_repr) {
       
  1074         _repr.destroy();
       
  1075     });
       
  1076     this.$.html("");
       
  1077     paper.remove();
       
  1078 }
       
  1079