diff -r 32e5f491ba1d -r 8a6eb26ac87f client/js/paper-renderer.js --- a/client/js/paper-renderer.js Wed May 14 14:52:34 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2679 +0,0 @@ -/* paper-renderer.js */ -"use strict"; - -(function(root) { - - var Rkns = root.Rkns, - _ = Rkns._, - $ = Rkns.$; - - /* Rkns.Renderer Object */ - - /* This object contains constants, utility functions and classes for Renkan's Graph Manipulation GUI */ - - var Renderer = Rkns.Renderer = {}; - - /* Rkns.Renderer._BaseRepresentation Class */ - - /* In Renkan, a "Representation" is a sort of ViewModel (in the MVVM paradigm) and bridges the gap between - * models (written with Backbone.js) and the view (written with Paper.js) - * Renkan's representations all inherit from Rkns.Renderer._BaseRepresentation '*/ - - var _BaseRepresentation = Renderer._BaseRepresentation = function(_renderer, _model) { - if (typeof _renderer !== "undefined") { - this.renderer = _renderer; - this.renkan = _renderer.renkan; - this.project = _renderer.renkan.project; - this.options = _renderer.renkan.options; - this.model = _model; - if (this.model) { - var _this = this; - this._changeBinding = function() { - _this.redraw(); - }; - this._removeBinding = function() { - _renderer.removeRepresentation(_this); - _(function() { - _renderer.redraw(); - }).defer(); - }; - this._selectBinding = function() { - _this.select(); - }; - this._unselectBinding = function() { - _this.unselect(); - }; - this.model.on("change", this._changeBinding ); - this.model.on("remove", this._removeBinding ); - this.model.on("select", this._selectBinding ); - this.model.on("unselect", this._unselectBinding ); - } - } - }; - - /* Rkns.Renderer._BaseRepresentation Methods */ - - _(_BaseRepresentation.prototype).extend({ - _super: function(_func) { - return _BaseRepresentation.prototype[_func].apply(this, Array.prototype.slice.call(arguments, 1)); - }, - redraw: function() {}, - moveTo: function() {}, - show: function() {}, - hide: function() {}, - select: function() { - if (this.model) { - this.model.trigger("selected"); - } - }, - unselect: function() { - if (this.model) { - this.model.trigger("unselected"); - } - }, - highlight: function() {}, - unhighlight: function() {}, - mousedown: function() {}, - mouseup: function() { - if (this.model) { - this.model.trigger("clicked"); - } - }, - destroy: function() { - if (this.model) { - this.model.off("change", this._changeBinding ); - this.model.off("remove", this._removeBinding ); - this.model.off("select", this._selectBinding ); - this.model.off("unselect", this._unselectBinding ); - } - } - }); - - /* End of Rkns.Renderer._BaseRepresentation Class */ - - /* Rkns.Renderer._BaseButton Class */ - - /* BaseButton is extended by contextual buttons that appear when hovering on nodes and edges */ - - var _BaseButton = Renderer._BaseButton = Rkns.Utils.inherit(_BaseRepresentation); - - _(_BaseButton.prototype).extend({ - moveTo: function(_pos) { - this.sector.moveTo(_pos); - }, - show: function() { - this.sector.show(); - }, - hide: function() { - this.sector.hide(); - }, - select: function() { - this.sector.select(); - }, - unselect: function(_newTarget) { - this.sector.unselect(); - if (!_newTarget || (_newTarget !== this.source_representation && _newTarget.source_representation !== this.source_representation)) { - this.source_representation.unselect(); - } - }, - destroy: function() { - this.sector.destroy(); - } - }); - - /* End of Rkns.Renderer._BaseButton Class */ - - /* Rkns.Renderer.Node Class */ - - /* The representation for the node : A circle, with an image inside and a text label underneath. - * The circle and the image are drawn on canvas and managed by Paper.js. - * The text label is an HTML node, managed by jQuery. */ - - var NodeRepr = Renderer.Node = Rkns.Utils.inherit(_BaseRepresentation); - - _(NodeRepr.prototype).extend({ - _init: function() { - this.renderer.node_layer.activate(); - this.type = "Node"; - this.circle = new paper.Path.Circle([0, 0], 1); - this.circle.__representation = this; - if (this.options.show_node_circles) { - this.circle.strokeWidth = this.options.node_stroke_width; - this.h_ratio = 1; - } else { - this.h_ratio = 0; - } - this.title = $('
<%-renkan.translate("Size:")%>-<%-node.size%>+
<% } %>' - + '<% if (options.show_node_editor_color) { %><%-renkan.translate("Created by:")%> <%- shortenText(node.created_by_title, 25) %>
<% } %>' - ), - readOnlyTemplate: _.template( - '<%-node.description%>
<% } %>' - + '<% if (node.image && options.show_node_tooltip_image) { %><%-renkan.translate("Created by:")%><%- shortenText(node.created_by_title, 25) %>
<% } %>' - ), - draw: function() { - var _model = this.source_representation.model, - _created_by = _model.get("created_by") || Rkns.Utils._USER_PLACEHOLDER(this.renkan), - _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate ), - _image_placeholder = this.options.static_url + "img/image-placeholder.png", - _size = (_model.get("size") || 0); - this.editor_$ - .html(_template({ - node: { - has_creator: !!_model.get("created_by"), - title: _model.get("title"), - uri: _model.get("uri"), - short_uri: Rkns.Utils.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40), - description: _model.get("description"), - image: _model.get("image") || "", - image_placeholder: _image_placeholder, - color: _model.get("color") || _created_by.get("color"), - clip_path: _model.get("clip_path") || false, - created_by_color: _created_by.get("color"), - created_by_title: _created_by.get("title"), - size: (_size > 0 ? "+" : "") + _size - }, - renkan: this.renkan, - options: this.options, - shortenText: Rkns.Utils.shortenText - })); - this.redraw(); - var _this = this, - closeEditor = function() { - _this.renderer.removeRepresentation(_this); - paper.view.draw(); - }; - - this.editor_$.find(".Rk-CloseX").click(closeEditor); - - this.editor_$.find(".Rk-Edit-Goto").click(function() { - if (!_model.get("uri")) { - return false; - } - }); - - if (this.renderer.isEditable()) { - - var onFieldChange = _(function() { - _(function() { - if (_this.renderer.isEditable()) { - var _data = { - title: _this.editor_$.find(".Rk-Edit-Title").val() - }; - if (_this.options.show_node_editor_uri) { - _data.uri = _this.editor_$.find(".Rk-Edit-URI").val(); - _this.editor_$.find(".Rk-Edit-Goto").attr("href",_data.uri || "#"); - } - if (_this.options.show_node_editor_image) { - _data.image = _this.editor_$.find(".Rk-Edit-Image").val(); - _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _data.image || _image_placeholder); - } - if (_this.options.show_node_editor_description) { - _data.description = _this.editor_$.find(".Rk-Edit-Description").val(); - } - _model.set(_data); - _this.redraw(); - } else { - closeEditor(); - } - - }).defer(); - }).throttle(500); - - this.editor_$.on("keyup", function(_e) { - if (_e.keyCode === 27) { - closeEditor(); - } - }); - - this.editor_$.find("input, textarea").on("change keyup paste", onFieldChange); - - this.editor_$.find(".Rk-Edit-Image-File").change(function() { - if (this.files.length) { - var f = this.files[0], - fr = new FileReader(); - if (f.type.substr(0,5) !== "image") { - alert(_this.renkan.translate("This file is not an image")); - return; - } - if (f.size > (_this.options.uploaded_image_max_kb * 1024)) { - alert(_this.renkan.translate("Image size must be under ") + _this.options.uploaded_image_max_kb + _this.renkan.translate("KB")); - return; - } - fr.onload = function(e) { - _this.editor_$.find(".Rk-Edit-Image").val(e.target.result); - onFieldChange(); - }; - fr.readAsDataURL(f); - } - }); - this.editor_$.find(".Rk-Edit-Title")[0].focus(); - - var _picker = _this.editor_$.find(".Rk-Edit-ColorPicker"); - - this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover( - function(_e) { - _e.preventDefault(); - _picker.show(); - }, - function(_e) { - _e.preventDefault(); - _picker.hide(); - } - ); - - _picker.find("li").hover( - function(_e) { - _e.preventDefault(); - _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); - }, - function(_e) { - _e.preventDefault(); - _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Utils._USER_PLACEHOLDER(_this.renkan)).get("color")); - } - ).click(function(_e) { - _e.preventDefault(); - if (_this.renderer.isEditable()) { - _model.set("color", $(this).attr("data-color")); - _picker.hide(); - paper.view.draw(); - } else { - closeEditor(); - } - }); - - var shiftSize = function(n) { - if (_this.renderer.isEditable()) { - var _newsize = n+(_model.get("size") || 0); - _this.editor_$.find(".Rk-Edit-Size-Value").text((_newsize > 0 ? "+" : "") + _newsize); - _model.set("size", _newsize); - paper.view.draw(); - } else { - closeEditor(); - } - }; - - this.editor_$.find(".Rk-Edit-Size-Down").click(function() { - shiftSize(-1); - return false; - }); - this.editor_$.find(".Rk-Edit-Size-Up").click(function() { - shiftSize(1); - return false; - }); - } else { - if (typeof this.source_representation.highlighted === "object") { - var titlehtml = this.source_representation.highlighted.replace(_(_model.get("title")).escape(),'$1'); - this.editor_$.find(".Rk-Display-Title" + (_model.get("uri") ? " a" : "")).html(titlehtml); - if (this.options.show_node_tooltip_description) { - this.editor_$.find(".Rk-Display-Description").html(this.source_representation.highlighted.replace(_(_model.get("description")).escape(),'$1')); - } - } - } - this.editor_$.find("img").load(function() { - _this.redraw(); - }); - }, - redraw: function() { - var _coords = this.source_representation.paper_coords; - Rkns.Utils.drawEditBox(this.options, _coords, this.editor_block, this.source_representation.circle_radius * .75, this.editor_$); - this.editor_$.show(); - paper.view.draw(); - } - }); - - /* */ - - var EdgeEditor = Renderer.EdgeEditor = Rkns.Utils.inherit(_BaseEditor); - - _(EdgeEditor.prototype).extend({ - template: _.template( - '<%- renkan.translate("Change edge direction") %>
<% } %>' - + '<% if (options.show_edge_editor_nodes) { %><%-renkan.translate("From:")%><%- shortenText(edge.from_title, 25) %>
' - + '<%-renkan.translate("To:")%><%- shortenText(edge.to_title, 25) %>
<% } %>' - + '<% if (options.show_edge_editor_creator && edge.has_creator) { %><%-renkan.translate("Created by:")%><%- shortenText(edge.created_by_title, 25) %>
<% } %>' - ), - readOnlyTemplate: _.template( - '<%-edge.description%>
' - + '<% if (options.show_edge_tooltip_nodes) { %><%-renkan.translate("From:")%><%- shortenText(edge.from_title, 25) %>
' - + '<%-renkan.translate("To:")%><%- shortenText(edge.to_title, 25) %>
<% } %>' - + '<% if (options.show_edge_tooltip_creator && edge.has_creator) { %><%-renkan.translate("Created by:")%><%- shortenText(edge.created_by_title, 25) %>
<% } %>' - ), - draw: function() { - var _model = this.source_representation.model, - _from_model = _model.get("from"), - _to_model = _model.get("to"), - _created_by = _model.get("created_by") || Rkns.Utils._USER_PLACEHOLDER(this.renkan), - _template = (this.renderer.isEditable() ? this.template : this.readOnlyTemplate); - this.editor_$ - .html(_template({ - edge: { - has_creator: !!_model.get("created_by"), - title: _model.get("title"), - uri: _model.get("uri"), - short_uri: Rkns.Utils.shortenText((_model.get("uri") || "").replace(/^(https?:\/\/)?(www\.)?/,'').replace(/\/$/,''),40), - description: _model.get("description"), - color: _model.get("color") || _created_by.get("color"), - from_title: _from_model.get("title"), - to_title: _to_model.get("title"), - from_color: _from_model.get("color") || (_from_model.get("created_by") || Rkns.Utils._USER_PLACEHOLDER(this.renkan)).get("color"), - to_color: _to_model.get("color") || (_to_model.get("created_by") || Rkns.Utils._USER_PLACEHOLDER(this.renkan)).get("color"), - created_by_color: _created_by.get("color"), - created_by_title: _created_by.get("title") - }, - renkan: this.renkan, - shortenText: Rkns.Utils.shortenText, - options: this.options - })); - this.redraw(); - var _this = this, - closeEditor = function() { - _this.renderer.removeRepresentation(_this); - paper.view.draw(); - }; - this.editor_$.find(".Rk-CloseX").click(closeEditor); - this.editor_$.find(".Rk-Edit-Goto").click(function() { - if (!_model.get("uri")) { - return false; - } - }); - - if (this.renderer.isEditable()) { - - var onFieldChange = _(function() { - _(function() { - if (_this.renderer.isEditable()) { - var _data = { - title: _this.editor_$.find(".Rk-Edit-Title").val() - }; - if (_this.options.show_edge_editor_uri) { - _data.uri = _this.editor_$.find(".Rk-Edit-URI").val(); - } - _this.editor_$.find(".Rk-Edit-Goto").attr("href",_data.uri || "#"); - _model.set(_data); - paper.view.draw(); - } else { - closeEditor(); - } - }).defer(); - }).throttle(500); - - this.editor_$.on("keyup", function(_e) { - if (_e.keyCode === 27) { - closeEditor(); - } - }); - - this.editor_$.find("input").on("keyup change paste", onFieldChange); - - this.editor_$.find(".Rk-Edit-Vocabulary").change(function() { - var e = $(this), - v = e.val(); - if (v) { - _this.editor_$.find(".Rk-Edit-Title").val(e.find(":selected").text()); - _this.editor_$.find(".Rk-Edit-URI").val(v); - onFieldChange(); - } - }); - this.editor_$.find(".Rk-Edit-Direction").click(function() { - if (_this.renderer.isEditable()) { - _model.set({ - from: _model.get("to"), - to: _model.get("from") - }); - _this.draw(); - } else { - closeEditor(); - } - }); - - var _picker = _this.editor_$.find(".Rk-Edit-ColorPicker"); - - this.editor_$.find(".Rk-Edit-ColorPicker-Wrapper").hover( - function(_e) { - _e.preventDefault(); - _picker.show(); - }, - function(_e) { - _e.preventDefault(); - _picker.hide(); - } - ); - - _picker.find("li").hover( - function(_e) { - _e.preventDefault(); - _this.editor_$.find(".Rk-Edit-Color").css("background", $(this).attr("data-color")); - }, - function(_e) { - _e.preventDefault(); - _this.editor_$.find(".Rk-Edit-Color").css("background", _model.get("color") || (_model.get("created_by") || Rkns.Utils._USER_PLACEHOLDER(_this.renkan)).get("color")); - } - ).click(function(_e) { - _e.preventDefault(); - if (_this.renderer.isEditable()) { - _model.set("color", $(this).attr("data-color")); - _picker.hide(); - paper.view.draw(); - } else { - closeEditor(); - } - }); - } - }, - redraw: function() { - var _coords = this.source_representation.paper_coords; - Rkns.Utils.drawEditBox(this.options, _coords, this.editor_block, 5, this.editor_$); - this.editor_$.show(); - paper.view.draw(); - } - }); - - /* */ - - var _NodeButton = Renderer._NodeButton = Rkns.Utils.inherit(_BaseButton); - - _(_NodeButton.prototype).extend({ - setSectorSize: function() { - var sectorInner = this.source_representation.circle_radius; - if (sectorInner !== this.lastSectorInner) { - if (this.sector) { - this.sector.destroy(); - } - this.sector = this.renderer.drawSector( - this, 1 + sectorInner, - Rkns.Utils._NODE_BUTTON_WIDTH + sectorInner, - this.startAngle, - this.endAngle, - 1, - this.imageName, - this.renkan.translate(this.text) - ); - this.lastSectorInner = sectorInner; - } - } - }); - - /* */ - - var NodeEditButton = Renderer.NodeEditButton = Rkns.Utils.inherit(_NodeButton); - - _(NodeEditButton.prototype).extend({ - _init: function() { - this.type = "Node-edit-button"; - this.lastSectorInner = 0; - this.startAngle = -135; - this.endAngle = -45; - this.imageName = "edit"; - this.text = "Edit"; - }, - mouseup: function() { - if (!this.renderer.is_dragging) { - this.source_representation.openEditor(); - } - } - }); - - /* */ - - var NodeRemoveButton = Renderer.NodeRemoveButton = Rkns.Utils.inherit(_NodeButton); - - _(NodeRemoveButton.prototype).extend({ - _init: function() { - this.type = "Node-remove-button"; - this.lastSectorInner = 0; - this.startAngle = 0; - this.endAngle = 90; - this.imageName = "remove"; - this.text = "Remove"; - }, - mouseup: function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - this.renderer.removeRepresentationsOfType("editor"); - if (this.renderer.isEditable()) { - if (this.options.element_delete_delay) { - var delid = Rkns.Utils.getUID("delete"); - this.renderer.delete_list.push({ - id: delid, - time: new Date().valueOf() + this.options.element_delete_delay - }); - this.source_representation.model.set("delete_scheduled", delid); - } else { - if (confirm(this.renkan.translate('Do you really wish to remove node ') + '"' + this.source_representation.model.get("title") + '"?')) { - this.project.removeNode(this.source_representation.model); - } - } - } - } - }); - - /* */ - - var NodeRevertButton = Renderer.NodeRevertButton = Rkns.Utils.inherit(_NodeButton); - - _(NodeRevertButton.prototype).extend({ - _init: function() { - this.type = "Node-revert-button"; - this.lastSectorInner = 0; - this.startAngle = -135; - this.endAngle = 135; - this.imageName = "revert"; - this.text = "Cancel deletion"; - }, - mouseup: function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - if (this.renderer.isEditable()) { - this.source_representation.model.unset("delete_scheduled"); - } - } - }); - - /* */ - - var NodeLinkButton = Renderer.NodeLinkButton = Rkns.Utils.inherit(_NodeButton); - - _(NodeLinkButton.prototype).extend({ - _init: function() { - this.type = "Node-link-button"; - this.lastSectorInner = 0; - this.startAngle = 90; - this.endAngle = 180; - this.imageName = "link"; - this.text = "Link to another node"; - }, - mousedown: function(_event, _isTouch) { - if (this.renderer.isEditable()) { - var _off = this.renderer.canvas_$.offset(), - _point = new paper.Point([ - _event.pageX - _off.left, - _event.pageY - _off.top - ]); - this.renderer.click_target = null; - this.renderer.removeRepresentationsOfType("editor"); - this.renderer.addTempEdge(this.source_representation, _point); - } - } - }); - - /* */ - - var NodeEnlargeButton = Renderer.NodeEnlargeButton = Rkns.Utils.inherit(_NodeButton); - - _(NodeEnlargeButton.prototype).extend({ - _init: function() { - this.type = "Node-enlarge-button"; - this.lastSectorInner = 0; - this.startAngle = -45; - this.endAngle = 0; - this.imageName = "enlarge"; - this.text = "Enlarge"; - }, - mouseup: function() { - var _newsize = 1 + (this.source_representation.model.get("size") || 0); - this.source_representation.model.set("size", _newsize); - this.source_representation.select(); - this.select(); - paper.view.draw(); - } - }); - - /* */ - - var NodeShrinkButton = Renderer.NodeShrinkButton = Rkns.Utils.inherit(_NodeButton); - - _(NodeShrinkButton.prototype).extend({ - _init: function() { - this.type = "Node-shrink-button"; - this.lastSectorInner = 0; - this.startAngle = -180; - this.endAngle = -135; - this.imageName = "shrink"; - this.text = "Shrink"; - }, - mouseup: function() { - var _newsize = -1 + (this.source_representation.model.get("size") || 0); - this.source_representation.model.set("size", _newsize); - this.source_representation.select(); - this.select(); - paper.view.draw(); - } - }); - - /* */ - - var EdgeEditButton = Renderer.EdgeEditButton = Rkns.Utils.inherit(_BaseButton); - - _(EdgeEditButton.prototype).extend({ - _init: function() { - this.type = "Edge-edit-button"; - this.sector = this.renderer.drawSector(this, Rkns.Utils._EDGE_BUTTON_INNER, Rkns.Utils._EDGE_BUTTON_OUTER, -270, -90, 1, "edit", this.renkan.translate("Edit")); - }, - mouseup: function() { - if (!this.renderer.is_dragging) { - this.source_representation.openEditor(); - } - } - }); - - /* */ - - var EdgeRemoveButton = Renderer.EdgeRemoveButton = Rkns.Utils.inherit(_BaseButton); - - _(EdgeRemoveButton.prototype).extend({ - _init: function() { - this.type = "Edge-remove-button"; - this.sector = this.renderer.drawSector(this, Rkns.Utils._EDGE_BUTTON_INNER, Rkns.Utils._EDGE_BUTTON_OUTER, -90, 90, 1, "remove", this.renkan.translate("Remove")); - }, - mouseup: function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - this.renderer.removeRepresentationsOfType("editor"); - if (this.renderer.isEditable()) { - if (this.options.element_delete_delay) { - var delid = Rkns.Utils.getUID("delete"); - this.renderer.delete_list.push({ - id: delid, - time: new Date().valueOf() + this.options.element_delete_delay - }); - this.source_representation.model.set("delete_scheduled", delid); - } else { - if (confirm(this.renkan.translate('Do you really wish to remove edge ') + '"' + this.source_representation.model.get("title") + '"?')) { - this.project.removeEdge(this.source_representation.model); - } - } - } - } - }); - - /* */ - - var EdgeRevertButton = Renderer.EdgeRevertButton = Rkns.Utils.inherit(_BaseButton); - - _(EdgeRevertButton.prototype).extend({ - _init: function() { - this.type = "Edge-revert-button"; - this.sector = this.renderer.drawSector(this, Rkns.Utils._EDGE_BUTTON_INNER, Rkns.Utils._EDGE_BUTTON_OUTER, -135, 135, 1, "revert", this.renkan.translate("Cancel deletion")); - }, - mouseup: function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - if (this.renderer.isEditable()) { - this.source_representation.model.unset("delete_scheduled"); - } - } - }); - - /* */ - - var MiniFrame = Renderer.MiniFrame = Rkns.Utils.inherit(_BaseRepresentation); - - _(MiniFrame.prototype).extend({ - paperShift: function(_delta) { - this.renderer.offset = this.renderer.offset.subtract(_delta.divide(this.renderer.minimap.scale).multiply(this.renderer.scale)); - this.renderer.redraw(); - }, - mouseup: function(_delta) { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - } - }); - - /* */ - - var Scene = Renderer.Scene = function(_renkan) { - this.renkan = _renkan; - this.$ = $(".Rk-Render"); - this.representations = []; - this.$.html(this.template(_renkan)); - this.onStatusChange(); - this.canvas_$ = this.$.find(".Rk-Canvas"); - this.labels_$ = this.$.find(".Rk-Labels"); - this.editor_$ = this.$.find(".Rk-Editor"); - this.notif_$ = this.$.find(".Rk-Notifications"); - paper.setup(this.canvas_$[0]); - this.scale = 1; - this.initialScale = 1; - this.offset = paper.view.center; - this.totalScroll = 0; - this.mouse_down = false; - this.click_target = null; - this.selected_target = null; - this.edge_layer = new paper.Layer(); - this.node_layer = new paper.Layer(); - this.buttons_layer = new paper.Layer(); - this.delete_list = []; - - if (_renkan.options.show_minimap) { - this.minimap = { - background_layer: new paper.Layer(), - edge_layer: new paper.Layer(), - node_layer: new paper.Layer(), - node_group: new paper.Group(), - size: new paper.Size( _renkan.options.minimap_width, _renkan.options.minimap_height ) - }; - - this.minimap.background_layer.activate(); - this.minimap.topleft = paper.view.bounds.bottomRight.subtract(this.minimap.size); - this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4])); - this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color; - this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color; - this.minimap.rectangle.strokeWidth = 4; - this.minimap.offset = new paper.Point(this.minimap.size.divide(2)); - this.minimap.scale = .1; - - this.minimap.node_layer.activate(); - this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size); - this.minimap.node_group.addChild(this.minimap.cliprectangle); - this.minimap.node_group.clipped = true; - this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size); - this.minimap.node_group.addChild(this.minimap.miniframe); - this.minimap.miniframe.fillColor = '#c0c0ff'; - this.minimap.miniframe.opacity = .3; - this.minimap.miniframe.strokeColor = '#000080'; - this.minimap.miniframe.strokeWidth = 3; - this.minimap.miniframe.__representation = new MiniFrame(this, null); - } - - this.throttledPaperDraw = _(function() { - paper.view.draw(); - }).throttle(100); - - this.bundles = []; - this.click_mode = false; - - var _this = this, - _allowScroll = true, - _originalScale = 1, - _zooming = false, - _lastTapX = 0, - _lastTapY = 0; - - this.image_cache = {}; - this.icon_cache = {}; - - ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) { - var img = new Image(); - img.src = _renkan.options.static_url + 'img/' + imgname + '.png'; - _this.icon_cache[imgname] = img; - }); - - var throttledMouseMove = _.throttle(function(_event, _isTouch) { - _this.onMouseMove(_event, _isTouch); - }, Rkns.Utils._MOUSEMOVE_RATE); - - this.canvas_$.on({ - mousedown: function(_event) { - _event.preventDefault(); - _this.onMouseDown(_event, false); - }, - mousemove: function(_event) { - _event.preventDefault(); - throttledMouseMove(_event, false); - }, - mouseup: function(_event) { - _event.preventDefault(); - _this.onMouseUp(_event, false); - }, - mousewheel: function(_event, _delta) { - if(_renkan.options.zoom_on_scroll) { - _event.preventDefault(); - if (_allowScroll) { - _this.onScroll(_event, _delta); - } - } - }, - touchstart: function(_event) { - _event.preventDefault(); - var _touches = _event.originalEvent.touches[0]; - if ( - _renkan.options.allow_double_click - && new Date() - _lastTap < Rkns.Utils._DOUBLETAP_DELAY - && ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Rkns.Utils._DOUBLETAP_DISTANCE ) - ) { - _lastTap = 0; - _this.onDoubleClick(_touches); - } else { - _lastTap = new Date(); - _lastTapX = _touches.pageX; - _lastTapY = _touches.pageY; - _originalScale = _this.scale; - _zooming = false; - _this.onMouseDown(_touches, true); - } - }, - touchmove: function(_event) { - _event.preventDefault(); - _lastTap = 0; - if (_event.originalEvent.touches.length == 1) { - _this.onMouseMove(_event.originalEvent.touches[0], true); - } else { - if (!_zooming) { - _this.onMouseUp(_event.originalEvent.touches[0], true); - _this.click_target = null; - _this.is_dragging = false; - _zooming = true; - } - if (_event.originalEvent.scale === "undefined") { - return; - } - var _newScale = _event.originalEvent.scale * _originalScale, - _scaleRatio = _newScale / _this.scale, - _newOffset = new paper.Point([ - _this.canvas_$.width(), - _this.canvas_$.height() - ]).multiply( .5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio )); - _this.setScale(_newScale, _newOffset); - } - }, - touchend: function(_event) { - _event.preventDefault(); - _this.onMouseUp(_event.originalEvent.changedTouches[0], true); - }, - dblclick: function(_event) { - _event.preventDefault(); - if (_renkan.options.allow_double_click) { - _this.onDoubleClick(_event); - } - }, - mouseleave: function(_event) { - _event.preventDefault(); - _this.onMouseUp(_event, false); - _this.click_target = null; - _this.is_dragging = false; - }, - dragover: function(_event) { - _event.preventDefault(); - }, - dragenter: function(_event) { - _event.preventDefault(); - _allowScroll = false; - }, - dragleave: function(_event) { - _event.preventDefault(); - _allowScroll = true; - }, - drop: function(_event) { - _event.preventDefault(); - _allowScroll = true; - var res = {}; - _(_event.originalEvent.dataTransfer.types).each(function(t) { - try { - res[t] = _event.originalEvent.dataTransfer.getData(t); - } catch(e) {} - }); - var text = _event.originalEvent.dataTransfer.getData("Text"); - if (typeof text === "string") { - switch(text[0]) { - case "{": - case "[": - try { - var data = JSON.parse(text); - _(res).extend(data); - } - catch(e) { - if (!res["text/plain"]) { - res["text/plain"] = text; - } - } - break; - case "<": - if (!res["text/html"]) { - res["text/html"] = text; - } - break; - default: - if (!res["text/plain"]) { - res["text/plain"] = text; - } - } - } - var url = _event.originalEvent.dataTransfer.getData("URL"); - if (url && !res["text/uri-list"]) { - res["text/uri-list"] = url; - } - _this.dropData(res, _event.originalEvent); - } - }); - - var bindClick = function(selector, fname) { - _this.$.find(selector).click(function(evt) { - _this[fname](evt); - return false; - }); - }; - - bindClick(".Rk-ZoomOut", "zoomOut"); - bindClick(".Rk-ZoomIn", "zoomIn"); - bindClick(".Rk-ZoomFit", "autoScale"); - this.$.find(".Rk-ZoomSave").click( function() { - // Save scale and offset point - _this.renkan.project.addView( { zoom_level:_this.scale, offset_x:_this.offset.x, offset_y:_this.offset.y } ); - }); - this.$.find(".Rk-ZoomSetSaved").click( function() { - var view = _this.renkan.project.get("views").last(); - if(view){ - _this.setScale(view.get("zoom_level"), new paper.Point(view.get("offset_x"), view.get("offset_y"))); - } - }); - if(this.renkan.read_only && !isNaN(parseInt(this.renkan.options.default_view))){ - this.$.find(".Rk-ZoomSetSaved").show(); - } - this.$.find(".Rk-CurrentUser").mouseenter( - function() { _this.$.find(".Rk-UserList").slideDown(); } - ); - this.$.find(".Rk-Users").mouseleave( - function() { _this.$.find(".Rk-UserList").slideUp(); } - ); - bindClick(".Rk-FullScreen-Button", "fullScreen"); - bindClick(".Rk-AddNode-Button", "addNodeBtn"); - bindClick(".Rk-AddEdge-Button", "addEdgeBtn"); - bindClick(".Rk-Save-Button", "save"); - bindClick(".Rk-Open-Button", "open"); - this.$.find(".Rk-Bookmarklet-Button") - .attr("href","javascript:" + Rkns.Utils._BOOKMARKLET_CODE(_renkan)) - .click(function(){ - _this.notif_$ - .text(_renkan.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan.")) - .fadeIn() - .delay(5000) - .fadeOut(); - return false; - }); - this.$.find(".Rk-TopBar-Button").mouseover(function() { - $(this).find(".Rk-TopBar-Tooltip").show(); - }).mouseout(function() { - $(this).find(".Rk-TopBar-Tooltip").hide(); - }); - bindClick(".Rk-Fold-Bins", "foldBins"); - - paper.view.onResize = function(_event) { - // Because of paper bug which does not calculate the good height (and width a fortiori) - // We have to update manually the canvas's height - paper.view._viewSize.height = _event.size.height = _this.canvas_$.parent().height(); - - if (_this.minimap) { - _this.minimap.topleft = paper.view.bounds.bottomRight.subtract(_this.minimap.size); - _this.minimap.rectangle.fitBounds(_this.minimap.topleft.subtract([2,2]), _this.minimap.size.add([4,4])); - _this.minimap.cliprectangle.fitBounds(_this.minimap.topleft, _this.minimap.size); - } - _this.redraw(); - }; - - var _thRedraw = _.throttle(function() { - _this.redraw(); - },50); - - this.addRepresentations("Node", this.renkan.project.get("nodes")); - this.addRepresentations("Edge", this.renkan.project.get("edges")); - this.renkan.project.on("change:title", function() { - _this.$.find(".Rk-PadTitle").val(_renkan.project.get("title")); - }); - - this.$.find(".Rk-PadTitle").on("keyup input paste", function() { - _renkan.project.set({"title": $(this).val()}); - }); - - var _thRedrawUsers = _.throttle(function() { - _this.redrawUsers(); - }, 100); - - _thRedrawUsers(); - - // register model events - this.renkan.project.on("add:users remove:users", _thRedrawUsers); - - this.renkan.project.on("add:views remove:views", function(_node) { - if(_this.renkan.project.get('views').length > 0) { - _this.$.find(".Rk-ZoomSetSaved").show(); - } - else { - _this.$.find(".Rk-ZoomSetSaved").hide(); - } - }); - - this.renkan.project.on("add:nodes", function(_node) { - _this.addRepresentation("Node", _node); - _thRedraw(); - }); - this.renkan.project.on("add:edges", function(_edge) { - _this.addRepresentation("Edge", _edge); - _thRedraw(); - }); - this.renkan.project.on("change:title", function(_model, _title) { - var el = _this.$.find(".Rk-PadTitle"); - if (el.is("input")) { - if (el.val() !== _title) { - el.val(_title); - } - } else { - el.text(_title); - } - }); - - if (_renkan.options.size_bug_fix) { - var _delay = ( - typeof _renkan.options.size_bug_fix === "number" - ? _renkan.options.size_bug_fix - : 500 - ); - window.setTimeout( - function() { - _this.fixSize(true); - }, - _delay - ); - } - - if (_renkan.options.force_resize) { - $(window).resize(function() { - _this.fixSize(false); - }); - } - - if (_renkan.options.show_user_list && _renkan.options.user_color_editable) { - var $cpwrapper = this.$.find(".Rk-Users .Rk-Edit-ColorPicker-Wrapper"), - $cplist = this.$.find(".Rk-Users .Rk-Edit-ColorPicker"); - - $cpwrapper.hover( - function(_e) { - if (_this.isEditable()) { - _e.preventDefault(); - $cplist.show(); - } - }, - function(_e) { - _e.preventDefault(); - $cplist.hide(); - } - ); - - $cplist.find("li").mouseenter( - function(_e) { - if (_this.isEditable()) { - _e.preventDefault(); - _this.$.find(".Rk-CurrentUser-Color").css("background", $(this).attr("data-color")); - } - } - ); - } - - if (_renkan.options.show_search_field) { - - var lastval = ''; - - this.$.find(".Rk-GraphSearch-Field").on("keyup change paste input", function() { - var $this = $(this), - val = $this.val(); - if (val === lastval) { - return; - } - lastval = val; - if (val.length < 2) { - _renkan.project.get("nodes").each(function(n) { - _this.getRepresentationByModel(n).unhighlight(); - }); - } else { - var rxs = Rkns.Utils.regexpFromTextOrArray(val); - _renkan.project.get("nodes").each(function(n) { - if (rxs.test(n.get("title")) || rxs.test(n.get("description"))) { - _this.getRepresentationByModel(n).highlight(rxs); - } else { - _this.getRepresentationByModel(n).unhighlight(); - } - }); - } - }); - } - - this.redraw(); - - window.setInterval(function() { - var _now = new Date().valueOf(); - _this.delete_list.forEach(function(d) { - if (_now >= d.time) { - var el = _renkan.project.get("nodes").findWhere({"delete_scheduled":d.id}); - if (el) { - project.removeNode(el); - } - el = _renkan.project.get("edges").findWhere({"delete_scheduled":d.id}); - if (el) { - project.removeEdge(el); - } - } - }); - _this.delete_list = _this.delete_list.filter(function(d) { - return _renkan.project.get("nodes").findWhere({"delete_scheduled":d.id}) || _renkan.project.get("edges").findWhere({"delete_scheduled":d.id}); - }); - }, 500); - - if (this.minimap) { - window.setInterval(function() { - _this.rescaleMinimap(); - }, 2000); - } - - }; - - _(Scene.prototype).extend({ - template: _.template( - '<% if (options.show_top_bar) { %>