diff -r 1615c7e4ef9d -r 9521347ede1d src/js/libs/renkan.js --- a/src/js/libs/renkan.js Tue Apr 23 15:23:20 2013 +0200 +++ b/src/js/libs/renkan.js Wed May 15 15:35:15 2013 +0200 @@ -1,3232 +1,3306 @@ -/* - * Copyright 2012-2013 Institut de recherche et d'innovation - * contributor(s) : Yves-Marie Haussonne, Raphael Velt, Samuel Huron - * - * contact@iri.centrepompidou.fr - * http://www.iri.centrepompidou.fr - * - * This software is a computer program whose purpose is to show and add annotations on a video . - * This software is governed by the CeCILL-C license under French law and - * abiding by the rules of distribution of free software. You can use, - * modify and/ or redistribute the software under the terms of the CeCILL-C - * license as circulated by CEA, CNRS and INRIA at the following URL - * "http://www.cecill.info". - * - * The fact that you are presently reading this means that you have had - * knowledge of the CeCILL-C license and that you accept its terms. -*/ - -/* Declaring the Renkan Namespace Rkns and Default values */ - -if (typeof Rkns !== "object") { - Rkns = {} -} - -Rkns.$ = jQuery; - -Rkns._ = _; - -Rkns.VERSION = '0.2'; - -Rkns.pickerColors = ["#8f1919", "#a80000", "#d82626", "#ff0000", "#e87c7c", "#ff6565", "#f7d3d3", "#fecccc", - "#8f5419", "#a85400", "#d87f26", "#ff7f00", "#e8b27c", "#ffb265", "#f7e5d3", "#fee5cc", - "#8f8f19", "#a8a800", "#d8d826", "#feff00", "#e8e87c", "#feff65", "#f7f7d3", "#fefecc", - "#198f19", "#00a800", "#26d826", "#00ff00", "#7ce87c", "#65ff65", "#d3f7d3", "#ccfecc", - "#198f8f", "#00a8a8", "#26d8d8", "#00feff", "#7ce8e8", "#65feff", "#d3f7f7", "#ccfefe", - "#19198f", "#0000a8", "#2626d8", "#0000ff", "#7c7ce8", "#6565ff", "#d3d3f7", "#ccccfe", - "#8f198f", "#a800a8", "#d826d8", "#ff00fe", "#e87ce8", "#ff65fe", "#f7d3f7", "#feccfe", - "#000000", "#242424", "#484848", "#6d6d6d", "#919191", "#b6b6b6", "#dadada", "#ffffff"]; - -Rkns._BaseBin = function(_renkan, _opts) { - if (typeof _renkan !== "undefined") { - this.renkan = _renkan; - this.renkan.$.find(".Rk-Bin-Main").hide(); - this.$ = Rkns.$('
<%-renkan.translate("Size:")%>-<%-node.size%>+
' - + '<%-renkan.translate("Created by:")%> <%- Rkns.Renderer.shortenText(node.created_by_title, 25) %>
<% } %>' -); - -Rkns.Renderer.NodeEditor.prototype.readOnlyTemplate = Rkns._.template( - '<%-node.description%>
' - + '<% if (node.image) { %><%-renkan.translate("Created by:")%><%- Rkns.Renderer.shortenText(node.created_by_title, 25) %>
<% } %>' -); - -Rkns.Renderer.NodeEditor.prototype.draw = function() { - var _model = this.source_representation.model, - _created_by = _model.get("created_by") || Rkns.Renderer._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.Renderer.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"), - created_by_color: _created_by.get("color"), - created_by_title: _created_by.get("title"), - size: (_size > 0 ? "+" : "") + _size - }, - renkan: this.renkan - })); - this.redraw(); - var _this = this, - closeEditor = function() { - _this.renderer.removeRepresentation(_this); - paper.view.draw(); - } - - this.editor_$.find(".Rk-CloseX").click(closeEditor); - - if (this.renderer.isEditable()) { - - var onFieldChange = Rkns._(function() { - Rkns._(function() { - if (_this.renderer.isEditable()) { - var _uri = _this.editor_$.find(".Rk-Edit-URI").val(), - _image = _this.editor_$.find(".Rk-Edit-Image").val(); - _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image || _image_placeholder); - _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri); - var _data = { - title: _this.editor_$.find(".Rk-Edit-Title").val(), - description: _this.editor_$.find(".Rk-Edit-Description").val(), - uri: _uri, - image: _image - } - _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 > (Rkns.Renderer._IMAGE_MAX_KB * 1024)) { - alert(_this.renkan.translate("Image size must be under ")+Rkns.Renderer._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.Renderer._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(); - } - }); - - function shiftSize(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; - }); - } - this.editor_$.find("img").load(function() { - _this.redraw(); - }); -} - -Rkns.Renderer.NodeEditor.prototype.redraw = function() { - var _coords = this.source_representation.paper_coords; - Rkns.Renderer.drawEditBox(this.options, _coords, this.editor_block, this.source_representation.circle_radius * .75, this.editor_$); - this.editor_$.show(); - paper.view.draw(); -} - -/* */ - -Rkns.Renderer.EdgeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseEditor); - -Rkns.Renderer.EdgeEditor.prototype.template = Rkns._.template( - '<%- renkan.translate("Change edge direction") %>
' - + '<%-renkan.translate("From:")%><%- Rkns.Renderer.shortenText(edge.from_title, 25) %>
' - + '<%-renkan.translate("To:")%><%- Rkns.Renderer.shortenText(edge.to_title, 25) %>
' - + '<% if (edge.has_creator) { %><%-renkan.translate("Created by:")%><%- Rkns.Renderer.shortenText(edge.created_by_title, 25) %>
<% } %>' -); - -Rkns.Renderer.EdgeEditor.prototype.readOnlyTemplate = Rkns._.template( - '<%-edge.description%>
' - + '<%-renkan.translate("From:")%><%- Rkns.Renderer.shortenText(edge.from_title, 25) %>
' - + '<%-renkan.translate("To:")%><%- Rkns.Renderer.shortenText(edge.to_title, 25) %>
' - + '<% if (edge.has_creator) { %><%-renkan.translate("Created by:")%><%- Rkns.Renderer.shortenText(edge.created_by_title, 25) %>
<% } %>' -); - -Rkns.Renderer.EdgeEditor.prototype.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.Renderer._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.Renderer.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.Renderer._USER_PLACEHOLDER(this.renkan)).get("color"), - to_color: _to_model.get("color") || (_to_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color"), - created_by_color: _created_by.get("color"), - created_by_title: _created_by.get("title") - }, - renkan: this.renkan, - properties: this.options.properties - })); - this.redraw(); - var _this = this, - closeEditor = function() { - _this.renderer.removeRepresentation(_this); - paper.view.draw(); - } - this.editor_$.find(".Rk-CloseX").click(closeEditor); - - if (this.renderer.isEditable()) { - - var onFieldChange = Rkns._(function() { - Rkns._(function() { - if (_this.renderer.isEditable()) { - _this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val()); - var _data = { - title: _this.editor_$.find(".Rk-Edit-Title").val(), - uri: _this.editor_$.find(".Rk-Edit-URI").val() - } - _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.Renderer._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(); - } - }); - } -} - -Rkns.Renderer.EdgeEditor.prototype.redraw = function() { - var _coords = this.source_representation.paper_coords; - Rkns.Renderer.drawEditBox(this.options, _coords, this.editor_block, 5, this.editor_$); - this.editor_$.show(); - paper.view.draw(); -} - -/* */ - -Rkns.Renderer._NodeButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); - -Rkns.Renderer._NodeButton.prototype.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.Renderer._NODE_BUTTON_WIDTH + sectorInner, - this.startAngle, - this.endAngle, - 1, - this.imageName, - this.renkan.translate(this.text) - ); - this.lastSectorInner = sectorInner; - } -} - -/* */ - -Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); - -Rkns.Renderer.NodeEditButton.prototype._init = function() { - this.type = "Node-edit-button"; - this.lastSectorInner = 0; - this.startAngle = -135; - this.endAngle = -45; - this.imageName = "edit"; - this.text = "Edit"; -} - -Rkns.Renderer.NodeEditButton.prototype.mouseup = function() { - if (!this.renderer.is_dragging) { - this.source_representation.openEditor(); - } -} - -/* */ - -Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); - -Rkns.Renderer.NodeRemoveButton.prototype._init = function() { - this.type = "Node-remove-button"; - this.lastSectorInner = 0; - this.startAngle = 0; - this.endAngle = 90; - this.imageName = "remove"; - this.text = "Remove"; -} - -Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - this.renderer.removeRepresentationsOfType("editor"); - if (this.renderer.isEditable()) { - 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); - } -} - -/* */ - -Rkns.Renderer.NodeRevertButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); - -Rkns.Renderer.NodeRevertButton.prototype._init = function() { - this.type = "Node-revert-button"; - this.lastSectorInner = 0; - this.startAngle = -135; - this.endAngle = 135; - this.imageName = "revert"; - this.text = "Cancel deletion"; -} - -Rkns.Renderer.NodeRevertButton.prototype.mouseup = function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - if (this.renderer.isEditable()) { - this.source_representation.model.unset("delete_scheduled"); - } -} - -/* */ - -Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); - -Rkns.Renderer.NodeLinkButton.prototype._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"; -} - -Rkns.Renderer.NodeLinkButton.prototype.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); - } -} - -/* */ - -Rkns.Renderer.NodeEnlargeButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); - -Rkns.Renderer.NodeEnlargeButton.prototype._init = function() { - this.type = "Node-enlarge-button"; - this.lastSectorInner = 0; - this.startAngle = -45; - this.endAngle = 0; - this.imageName = "enlarge"; - this.text = "Enlarge"; -} - -Rkns.Renderer.NodeEnlargeButton.prototype.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(); -} - -/* */ - -Rkns.Renderer.NodeShrinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); - -Rkns.Renderer.NodeShrinkButton.prototype._init = function() { - this.type = "Node-shrink-button"; - this.lastSectorInner = 0; - this.startAngle = -180; - this.endAngle = -135; - this.imageName = "shrink"; - this.text = "Shrink"; -} - -Rkns.Renderer.NodeShrinkButton.prototype.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(); -} - -/* */ - -Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); - -Rkns.Renderer.EdgeEditButton.prototype._init = function() { - this.type = "Edge-edit-button"; - this.sector = this.renderer.drawSector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, -270, -90, 1, "edit", this.renkan.translate("Edit")); -} - -Rkns.Renderer.EdgeEditButton.prototype.mouseup = function() { - if (!this.renderer.is_dragging) { - this.source_representation.openEditor(); - } -} - -/* */ - -Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); - -Rkns.Renderer.EdgeRemoveButton.prototype._init = function() { - this.type = "Edge-remove-button"; - this.sector = this.renderer.drawSector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, -90, 90, 1, "remove", this.renkan.translate("Remove")); -} - -Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - this.renderer.removeRepresentationsOfType("editor"); - if (this.renderer.isEditable()) { - 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); - } -} - -/* */ - -Rkns.Renderer.EdgeRevertButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); - -Rkns.Renderer.EdgeRevertButton.prototype._init = function() { - this.type = "Edge-revert-button"; - this.sector = this.renderer.drawSector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, -135, 135, 1, "revert", this.renkan.translate("Cancel deletion")); -} - -Rkns.Renderer.EdgeRevertButton.prototype.mouseup = function() { - this.renderer.click_target = null; - this.renderer.is_dragging = false; - if (this.renderer.isEditable()) { - this.source_representation.model.unset("delete_scheduled"); - } -} - -/* */ - -Rkns.Renderer.MiniFrame = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); - -Rkns.Renderer.MiniFrame.prototype.paperShift = function(_delta) { - this.renderer.offset = this.renderer.offset.subtract(_delta.divide(this.renderer.minimap.scale).multiply(this.renderer.scale)); - this.renderer.redraw(); -} - -Rkns.Renderer.MiniFrame.prototype.mouseup = function(_delta) { - this.renderer.click_target = null; - this.renderer.is_dragging = false; -} - -/* */ - -Rkns.Renderer.Scene = function(_renkan) { - this.renkan = _renkan; - this.$ = Rkns.$(".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.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 Rkns.Renderer.MiniFrame(this, null); - } - - this.throttledPaperDraw = Rkns._(function() { - paper.view.draw(); - }).throttle(100); - - this.bundles = []; - this.click_mode = false; - - var _this = this, - _allowScroll = true, - _originalScale, - _zooming = false, - _lastTapDate, - _lastTapX, - _lastTapY; - - this.imageCache = {}; - - ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) { - var img = new Image(); - img.src = _renkan.options.static_url + 'img/' + imgname + '.png'; - _this.imageCache[imgname] = img; - }); - - var throttledMouseMove = _.throttle(function(_event, _isTouch) { - _this.onMouseMove(_event, _isTouch); - }, Rkns.Renderer._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) { - _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.Renderer._DOUBLETAP_DELAY - && ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Rkns.Renderer._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, _this.offset); - } - }, - 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 = {}; - Rkns._(_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); - } - }); - this.editor_$.find(".Rk-ZoomOut").click(function() { - var _newScale = _this.scale * Math.SQRT1_2, - _offset = new paper.Point([ - _this.canvas_$.width(), - _this.canvas_$.height() - ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 )); - _this.setScale( _newScale, _offset ); - }); - this.editor_$.find(".Rk-ZoomIn").click(function() { - var _newScale = _this.scale * Math.SQRT2, - _offset = new paper.Point([ - _this.canvas_$.width(), - _this.canvas_$.height() - ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 )); - _this.setScale( _newScale, _offset ); - }); - this.$.find(".Rk-CurrentUser").mouseenter( - function() { _this.$.find(".Rk-UserList").slideDown() } - ); - this.$.find(".Rk-Users").mouseleave( - function() { _this.$.find(".Rk-UserList").slideUp(); } - ); - this.$.find(".Rk-FullScreen-Button").click(function() { - var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen, - _el = _this.renkan.$[0], - _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"], - _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"]; - if (_isFull) { - for (var i = 0; i < _cancelMethods.length; i++) { - if (typeof document[_cancelMethods[i]] === "function") { - document[_cancelMethods[i]](); - break; - } - } - } else { - for (var i = 0; i < _requestMethods.length; i++) { - if (typeof _el[_requestMethods[i]] === "function") { - _el[_requestMethods[i]](); - break; - } - } - } - }); - this.$.find(".Rk-AddNode-Button").click(function() { - if (_this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) { - _this.click_mode = false; - _this.notif_$.hide(); - } else { - _this.click_mode = Rkns.Renderer._CLICKMODE_ADDNODE; - _this.notif_$.text(_renkan.translate("Click on the background canvas to add a node")).fadeIn(); - } - }); - this.$.find(".Rk-AddEdge-Button").click(function() { - if (_this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE || _this.click_mode === Rkns.Renderer._CLICKMODE_ENDEDGE) { - _this.click_mode = false; - _this.notif_$.hide(); - } else { - _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE; - _this.notif_$.text(_renkan.translate("Click on a first node to start the edge")).fadeIn(); - } - }); - this.$.find(".Rk-Bookmarklet-Button") - .attr("href","javascript:" + Rkns.Renderer._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() { - Rkns.$(this).find(".Rk-TopBar-Tooltip").show(); - }).mouseout(function() { - Rkns.$(this).find(".Rk-TopBar-Tooltip").hide(); - }); - this.$.find(".Rk-Fold-Bins").click(function() { - var bins = _renkan.$.find(".Rk-Bins"); - if (bins.offset().left < 0) { - bins.animate({left: 0},250); - _this.$.animate({left: 300},250,function() { - var w = _this.$.width(); - paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]); - }); - $(this).html("«"); - } else { - bins.animate({left: -300},250); - _this.$.animate({left: 0},250,function() { - var w = _this.$.width(); - paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]); - }); - $(this).html("»"); - } - }); - - paper.view.onResize = function(_event) { - _this.offset = _this.offset.add(_event.delta.divide(2)); - 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 = Rkns._.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()}); - }) - - this.renkan.project.get("users").each(function(_user) { - _this.addUser(_user); - }); - - this.renkan.project.on("add:users", function(_user) { - _this.addUser(_user); - }); - 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); - }); - } - - 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); - } - -} - -Rkns.Renderer.Scene.prototype.template = Rkns._.template( - '<% if (options.show_top_bar) { %><%-renkan.translate("Size:")%>-<%-node.size%>+
' + + '<%-renkan.translate("Created by:")%> <%- Rkns.Renderer.shortenText(node.created_by_title, 25) %>
<% } %>' +); + +Rkns.Renderer.NodeEditor.prototype.readOnlyTemplate = Rkns._.template( + '<%-node.description%>
' + + '<% if (node.image) { %><%-renkan.translate("Created by:")%><%- Rkns.Renderer.shortenText(node.created_by_title, 25) %>
<% } %>' +); + +Rkns.Renderer.NodeEditor.prototype.draw = function() { + var _model = this.source_representation.model, + _created_by = _model.get("created_by") || Rkns.Renderer._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.Renderer.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"), + created_by_color: _created_by.get("color"), + created_by_title: _created_by.get("title"), + size: (_size > 0 ? "+" : "") + _size + }, + renkan: this.renkan + })); + this.redraw(); + var _this = this, + closeEditor = function() { + _this.renderer.removeRepresentation(_this); + paper.view.draw(); + }; + + this.editor_$.find(".Rk-CloseX").click(closeEditor); + + if (this.renderer.isEditable()) { + + var onFieldChange = Rkns._(function() { + Rkns._(function() { + if (_this.renderer.isEditable()) { + var _uri = _this.editor_$.find(".Rk-Edit-URI").val(), + _image = _this.editor_$.find(".Rk-Edit-Image").val(); + _this.editor_$.find(".Rk-Edit-ImgPreview").attr("src", _image || _image_placeholder); + _this.editor_$.find(".Rk-Edit-Goto").attr("href",_uri); + var _data = { + title: _this.editor_$.find(".Rk-Edit-Title").val(), + description: _this.editor_$.find(".Rk-Edit-Description").val(), + uri: _uri, + image: _image + }; + _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 > (Rkns.Renderer._IMAGE_MAX_KB * 1024)) { + alert(_this.renkan.translate("Image size must be under ")+Rkns.Renderer._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.Renderer._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(); + } + }); + + function shiftSize(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; + }); + } + this.editor_$.find("img").load(function() { + _this.redraw(); + }); +}; + +Rkns.Renderer.NodeEditor.prototype.redraw = function() { + var _coords = this.source_representation.paper_coords; + Rkns.Renderer.drawEditBox(this.options, _coords, this.editor_block, this.source_representation.circle_radius * .75, this.editor_$); + this.editor_$.show(); + paper.view.draw(); +}; + +/* */ + +Rkns.Renderer.EdgeEditor = Rkns.Utils.inherit(Rkns.Renderer._BaseEditor); + +Rkns.Renderer.EdgeEditor.prototype.template = Rkns._.template( + '<%- renkan.translate("Change edge direction") %>
' + + '<%-renkan.translate("From:")%><%- Rkns.Renderer.shortenText(edge.from_title, 25) %>
' + + '<%-renkan.translate("To:")%><%- Rkns.Renderer.shortenText(edge.to_title, 25) %>
' + + '<% if (edge.has_creator) { %><%-renkan.translate("Created by:")%><%- Rkns.Renderer.shortenText(edge.created_by_title, 25) %>
<% } %>' +); + +Rkns.Renderer.EdgeEditor.prototype.readOnlyTemplate = Rkns._.template( + '<%-edge.description%>
' + + '<%-renkan.translate("From:")%><%- Rkns.Renderer.shortenText(edge.from_title, 25) %>
' + + '<%-renkan.translate("To:")%><%- Rkns.Renderer.shortenText(edge.to_title, 25) %>
' + + '<% if (edge.has_creator) { %><%-renkan.translate("Created by:")%><%- Rkns.Renderer.shortenText(edge.created_by_title, 25) %>
<% } %>' +); + +Rkns.Renderer.EdgeEditor.prototype.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.Renderer._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.Renderer.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.Renderer._USER_PLACEHOLDER(this.renkan)).get("color"), + to_color: _to_model.get("color") || (_to_model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER(this.renkan)).get("color"), + created_by_color: _created_by.get("color"), + created_by_title: _created_by.get("title") + }, + renkan: this.renkan, + properties: this.options.properties + })); + this.redraw(); + var _this = this, + closeEditor = function() { + _this.renderer.removeRepresentation(_this); + paper.view.draw(); + }; + this.editor_$.find(".Rk-CloseX").click(closeEditor); + + if (this.renderer.isEditable()) { + + var onFieldChange = Rkns._(function() { + Rkns._(function() { + if (_this.renderer.isEditable()) { + _this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val()); + var _data = { + title: _this.editor_$.find(".Rk-Edit-Title").val(), + uri: _this.editor_$.find(".Rk-Edit-URI").val() + }; + _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.Renderer._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(); + } + }); + } +}; + +Rkns.Renderer.EdgeEditor.prototype.redraw = function() { + var _coords = this.source_representation.paper_coords; + Rkns.Renderer.drawEditBox(this.options, _coords, this.editor_block, 5, this.editor_$); + this.editor_$.show(); + paper.view.draw(); +}; + +/* */ + +Rkns.Renderer._NodeButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); + +Rkns.Renderer._NodeButton.prototype.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.Renderer._NODE_BUTTON_WIDTH + sectorInner, + this.startAngle, + this.endAngle, + 1, + this.imageName, + this.renkan.translate(this.text) + ); + this.lastSectorInner = sectorInner; + } +}; + +/* */ + +Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); + +Rkns.Renderer.NodeEditButton.prototype._init = function() { + this.type = "Node-edit-button"; + this.lastSectorInner = 0; + this.startAngle = -135; + this.endAngle = -45; + this.imageName = "edit"; + this.text = "Edit"; +}; + +Rkns.Renderer.NodeEditButton.prototype.mouseup = function() { + if (!this.renderer.is_dragging) { + this.source_representation.openEditor(); + } +}; + +/* */ + +Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); + +Rkns.Renderer.NodeRemoveButton.prototype._init = function() { + this.type = "Node-remove-button"; + this.lastSectorInner = 0; + this.startAngle = 0; + this.endAngle = 90; + this.imageName = "remove"; + this.text = "Remove"; +}; + +Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() { + this.renderer.click_target = null; + this.renderer.is_dragging = false; + this.renderer.removeRepresentationsOfType("editor"); + if (this.renderer.isEditable()) { + 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); + } +}; + +/* */ + +Rkns.Renderer.NodeRevertButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); + +Rkns.Renderer.NodeRevertButton.prototype._init = function() { + this.type = "Node-revert-button"; + this.lastSectorInner = 0; + this.startAngle = -135; + this.endAngle = 135; + this.imageName = "revert"; + this.text = "Cancel deletion"; +}; + +Rkns.Renderer.NodeRevertButton.prototype.mouseup = function() { + this.renderer.click_target = null; + this.renderer.is_dragging = false; + if (this.renderer.isEditable()) { + this.source_representation.model.unset("delete_scheduled"); + } +}; + +/* */ + +Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); + +Rkns.Renderer.NodeLinkButton.prototype._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"; +}; + +Rkns.Renderer.NodeLinkButton.prototype.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); + } +}; + +/* */ + +Rkns.Renderer.NodeEnlargeButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); + +Rkns.Renderer.NodeEnlargeButton.prototype._init = function() { + this.type = "Node-enlarge-button"; + this.lastSectorInner = 0; + this.startAngle = -45; + this.endAngle = 0; + this.imageName = "enlarge"; + this.text = "Enlarge"; +}; + +Rkns.Renderer.NodeEnlargeButton.prototype.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(); +}; + +/* */ + +Rkns.Renderer.NodeShrinkButton = Rkns.Utils.inherit(Rkns.Renderer._NodeButton); + +Rkns.Renderer.NodeShrinkButton.prototype._init = function() { + this.type = "Node-shrink-button"; + this.lastSectorInner = 0; + this.startAngle = -180; + this.endAngle = -135; + this.imageName = "shrink"; + this.text = "Shrink"; +}; + +Rkns.Renderer.NodeShrinkButton.prototype.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(); +}; + +/* */ + +Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); + +Rkns.Renderer.EdgeEditButton.prototype._init = function() { + this.type = "Edge-edit-button"; + this.sector = this.renderer.drawSector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, -270, -90, 1, "edit", this.renkan.translate("Edit")); +}; + +Rkns.Renderer.EdgeEditButton.prototype.mouseup = function() { + if (!this.renderer.is_dragging) { + this.source_representation.openEditor(); + } +}; + +/* */ + +Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); + +Rkns.Renderer.EdgeRemoveButton.prototype._init = function() { + this.type = "Edge-remove-button"; + this.sector = this.renderer.drawSector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, -90, 90, 1, "remove", this.renkan.translate("Remove")); +}; + +Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() { + this.renderer.click_target = null; + this.renderer.is_dragging = false; + this.renderer.removeRepresentationsOfType("editor"); + if (this.renderer.isEditable()) { + 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); + } +}; + +/* */ + +Rkns.Renderer.EdgeRevertButton = Rkns.Utils.inherit(Rkns.Renderer._BaseButton); + +Rkns.Renderer.EdgeRevertButton.prototype._init = function() { + this.type = "Edge-revert-button"; + this.sector = this.renderer.drawSector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, -135, 135, 1, "revert", this.renkan.translate("Cancel deletion")); +}; + +Rkns.Renderer.EdgeRevertButton.prototype.mouseup = function() { + this.renderer.click_target = null; + this.renderer.is_dragging = false; + if (this.renderer.isEditable()) { + this.source_representation.model.unset("delete_scheduled"); + } +}; + +/* */ + +Rkns.Renderer.MiniFrame = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); + +Rkns.Renderer.MiniFrame.prototype.paperShift = function(_delta) { + this.renderer.offset = this.renderer.offset.subtract(_delta.divide(this.renderer.minimap.scale).multiply(this.renderer.scale)); + this.renderer.redraw(); +}; + +Rkns.Renderer.MiniFrame.prototype.mouseup = function(_delta) { + this.renderer.click_target = null; + this.renderer.is_dragging = false; +}; + +/* */ + +Rkns.Renderer.Scene = function(_renkan) { + this.renkan = _renkan; + this.$ = Rkns.$(".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.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 Rkns.Renderer.MiniFrame(this, null); + } + + this.throttledPaperDraw = Rkns._(function() { + paper.view.draw(); + }).throttle(100); + + this.bundles = []; + this.click_mode = false; + + var _this = this, + _allowScroll = true, + _originalScale, + _zooming = false, + _lastTapDate, + _lastTapX, + _lastTapY; + + this.imageCache = {}; + + ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) { + var img = new Image(); + img.src = _renkan.options.static_url + 'img/' + imgname + '.png'; + _this.imageCache[imgname] = img; + }); + + var throttledMouseMove = _.throttle(function(_event, _isTouch) { + _this.onMouseMove(_event, _isTouch); + }, Rkns.Renderer._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) { + _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.Renderer._DOUBLETAP_DELAY + && ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Rkns.Renderer._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, _this.offset); + } + }, + 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 = {}; + Rkns._(_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); + } + }); + this.editor_$.find(".Rk-ZoomOut").click(function() { + var _newScale = _this.scale * Math.SQRT1_2, + _offset = new paper.Point([ + _this.canvas_$.width(), + _this.canvas_$.height() + ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 )); + _this.setScale( _newScale, _offset ); + }); + this.editor_$.find(".Rk-ZoomIn").click(function() { + var _newScale = _this.scale * Math.SQRT2, + _offset = new paper.Point([ + _this.canvas_$.width(), + _this.canvas_$.height() + ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 )); + _this.setScale( _newScale, _offset ); + }); + this.$.find(".Rk-CurrentUser").mouseenter( + function() { _this.$.find(".Rk-UserList").slideDown(); } + ); + this.$.find(".Rk-Users").mouseleave( + function() { _this.$.find(".Rk-UserList").slideUp(); } + ); + this.$.find(".Rk-FullScreen-Button").click(function() { + var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen, + _el = _this.renkan.$[0], + _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"], + _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"]; + if (_isFull) { + for (var i = 0; i < _cancelMethods.length; i++) { + if (typeof document[_cancelMethods[i]] === "function") { + document[_cancelMethods[i]](); + break; + } + } + } else { + for (var i = 0; i < _requestMethods.length; i++) { + if (typeof _el[_requestMethods[i]] === "function") { + _el[_requestMethods[i]](); + break; + } + } + } + }); + this.$.find(".Rk-AddNode-Button").click(function() { + if (_this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) { + _this.click_mode = false; + _this.notif_$.hide(); + } else { + _this.click_mode = Rkns.Renderer._CLICKMODE_ADDNODE; + _this.notif_$.text(_renkan.translate("Click on the background canvas to add a node")).fadeIn(); + } + }); + this.$.find(".Rk-AddEdge-Button").click(function() { + if (_this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE || _this.click_mode === Rkns.Renderer._CLICKMODE_ENDEDGE) { + _this.click_mode = false; + _this.notif_$.hide(); + } else { + _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE; + _this.notif_$.text(_renkan.translate("Click on a first node to start the edge")).fadeIn(); + } + }); + this.$.find(".Rk-Bookmarklet-Button") + .attr("href","javascript:" + Rkns.Renderer._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() { + Rkns.$(this).find(".Rk-TopBar-Tooltip").show(); + }).mouseout(function() { + Rkns.$(this).find(".Rk-TopBar-Tooltip").hide(); + }); + this.$.find(".Rk-Fold-Bins").click(function() { + var bins = _renkan.$.find(".Rk-Bins"); + if (bins.offset().left < 0) { + bins.animate({left: 0},250); + _this.$.animate({left: 300},250,function() { + var w = _this.$.width(); + paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]); + }); + $(this).html("«"); + } else { + bins.animate({left: -300},250); + _this.$.animate({left: 0},250,function() { + var w = _this.$.width(); + paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]); + }); + $(this).html("»"); + } + }); + + paper.view.onResize = function(_event) { + _this.offset = _this.offset.add(_event.delta.divide(2)); + 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 = Rkns._.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()}); + }); + + this.renkan.project.get("users").each(function(_user) { + _this.addUser(_user); + }); + + this.renkan.project.on("add:users", function(_user) { + _this.addUser(_user); + }); + 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); + }); + } + + 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); + } + +}; + +Rkns.Renderer.Scene.prototype.template = Rkns._.template( + '<% if (options.show_top_bar) { %>