# HG changeset patch # User veltr # Date 1362075188 -3600 # Node ID f0873867143a6ca5ed427ae69c49aa24a874fdd8 # Parent 803dbeb7c919a62af5e4bd1b2918efae39f1da70 Added Drag-and-add bookmarklet diff -r 803dbeb7c919 -r f0873867143a client/css/renkan.css --- a/client/css/renkan.css Wed Feb 27 19:04:36 2013 +0100 +++ b/client/css/renkan.css Thu Feb 28 19:13:08 2013 +0100 @@ -79,7 +79,7 @@ } .Rk-PadTitle { - float: left; font-size: 14px; height: 16px; margin: 4px 5px; width: 200px; background: #666666; padding: 4px; border: 1px solid #333333; + float: left; font-size: 14px; height: 16px; margin: 4px 5px; width: 180px; background: #666666; padding: 4px; border: 1px solid #333333; border-radius: 3px; box-shadow: 0 1px 0 #505050; color: #ffffff; font-weight: bold; } @@ -132,31 +132,31 @@ } .Rk-AddNode-Button { - width: 34px; + width: 30px; background-position: -2px 0; } .Rk-AddNode-Button:hover { - background-position: 0 -35px; + background-position: -2px -35px; } .Rk-FullScreen-Button { - width: 34px; background-position: -34px 0; + width: 30px; background-position: -36px 0; } .Rk-FullScreen-Button:hover { - background-position: -34px -35px; + background-position: -36px -35px; } .Rk-AddEdge-Button { - width: 34px; background-position: -68px 0; + width: 30px; background-position: -70px 0; } .Rk-AddEdge-Button:hover { - background-position: -68px -35px; + background-position: -70px -35px; } .Rk-Save-Button { - width: 34px; background-position: -102px 0; + width: 30px; background-position: -104px 0; } .Rk-Save-Button.disabled { @@ -164,12 +164,29 @@ } .Rk-Save-Button:hover { - background-position: -102px -35px; + background-position: -104px -35px; } .Rk-Save-Button.disabled:hover { - opacity: 1; background-position: -102px 0; + opacity: 1; background-position: -104px 0; +} + +.Rk-Bookmarklet-Button { + width: 30px; background-position: -138px 0; +} + +.Rk-Bookmarklet-Button.disabled { + opacity: .5; cursor: default; } + +.Rk-Bookmarklet-Button:hover { + background-position: -138px -35px; +} + +.Rk-Bookmarklet-Button.disabled:hover { + opacity: 1; background-position: -138px 0; +} + /* Canvas */ .Rk-Canvas { @@ -305,38 +322,23 @@ /* Bins */ -.Rk-Title { - position: absolute; left: 0; top: 0; width: 300px; height: 35px; - background: #333333; - background: -moz-linear-gradient(top, #505050 5px, #1e1e1e 30px); - background: -webkit-linear-gradient(top, #505050 5px, #1e1e1e 30px); -} - -.Rk-Title h1 { - font-size: 18px; color: #ffffff; margin: 5px; +.Rk-Bins { + background: #ffffff; position: absolute; left: 0; top: 0; width: 299px; bottom: 0; + overflow: hidden; border-right: 1px solid #252525; } - -.Rk-Title:after { - background: #666666; - background: -moz-linear-gradient(top, #666666 20%, #333333 80%); - background: -webkit-linear-gradient(top, #666666 20%, #333333 80%); - content: ""; display: block; height: 35px; - left: 298px; position: absolute; top: 0; width: 1px; border-left: 1px solid #111111; -} - -.Rk-Bins { - background: #ffffff; position: absolute; left: 0; top: 35px; width: 299px; bottom: 0; - overflow: hidden; border-right: 1px solid #252525; +.Rk-Bins-Title { + width: 290px; height: 15px; line-height: 15px; padding: 15px 0 5px 10px; + background: #333333; font-size: 14px; color: #F0F0F0; + background: -moz-linear-gradient(top, #1e1e1e 5px, #606060 30px); + background: -webkit-linear-gradient(top, #1e1e1e 5px, #606060 30px); } /* Bin Search Field */ .Rk-Search-Form { - padding: 5px 10px; height: 27px; - background: #666666; - background: -moz-linear-gradient(top, #606060 20%, #909090 80%); - background: -webkit-linear-gradient(top, #606060 20%, #909090 80%); + padding: 0 10px 8px; height: 27px; + background: #606060; } .Rk-Search-Input, .Rk-Search-Select { diff -r 803dbeb7c919 -r f0873867143a client/img/topbarbuttons.png Binary file client/img/topbarbuttons.png has changed diff -r 803dbeb7c919 -r f0873867143a client/js/i18n.js --- a/client/js/i18n.js Wed Feb 27 19:04:36 2013 +0100 +++ b/client/js/i18n.js Thu Feb 28 19:13:08 2013 +0100 @@ -38,6 +38,7 @@ "Do you really wish to remove edge ": "Voulez-vous réellement supprimer le lien ", "This file is not an image": "Ce fichier n'est pas une image", "Image size must be under ": "L'image doit peser moins de ", + "Size:": "Taille :", "KB": "ko", "Choose from vocabulary:": "Choisir dans un vocabulaire :", "SKOS Documentation properties": "SKOS: Propriétés documentaires", diff -r 803dbeb7c919 -r f0873867143a client/js/main.js --- a/client/js/main.js Wed Feb 27 19:04:36 2013 +0100 +++ b/client/js/main.js Thu Feb 28 19:13:08 2013 +0100 @@ -28,7 +28,14 @@ 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.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") { @@ -122,12 +129,26 @@ }); }); } + if (typeof _opts.bookmarklet_url !== "string") { + _opts.bookmarklet_url = "js/bookmarklet.js"; + } this.project = new Rkns.Models.Project(); this.language = _opts.language; this.static_url = _opts.static_url; this.show_bins = _opts.show_bins; this.read_only = _opts.read_only; this.properties = _opts.properties; + + function getAbsoluteURL(url) { + var tmp = document.createElement('img'); + tmp.src = url; + var res = tmp.src; + tmp.src = null; + return res; + } + + this.bookmarklet_url = getAbsoluteURL(_opts.bookmarklet_url); + this.translate = function(_text) { return (Rkns.i18n[_opts.language] || Rkns.i18n[_opts.language.substr(0,2)] || {})[_text] || _text; } @@ -230,7 +251,7 @@ } Rkns.Renkan.prototype.template = Rkns._.template( - '<% if (show_bins) { %>

<%- translate("Renkan") %>

' + '<% if (show_bins) { %>

<%- translate("Select contents:")%>

' + '
" />' + '
    ' + '
    ' diff -r 803dbeb7c919 -r f0873867143a client/js/paper-renderer.js --- a/client/js/paper-renderer.js Wed Feb 27 19:04:36 2013 +0100 +++ b/client/js/paper-renderer.js Thu Feb 28 19:13:08 2013 +0100 @@ -1,6 +1,6 @@ Rkns.Renderer = { - _MARGIN_X: 80, - _MARGIN_Y: 50, + _MINIMAP_MARGIN_X: 20, + _MINIMAP_MARGIN_Y: 20, _MIN_DRAG_DISTANCE: 2, _NODE_SIZE_BASE: 25, _NODE_BUTTON_WIDTH: 40, @@ -22,6 +22,8 @@ _CLICKMODE_ENDEDGE : 3, _IMAGE_MAX_KB : 500, _NODE_SIZE_STEP: Math.LN2/4, + _MINIMAP_WIDTH: 160, + _MINIMAP_HEIGHT: 120, _USER_PLACEHOLDER : { color: "#000000", title: "(unknown user)", @@ -106,6 +108,7 @@ _textX = Math.cos(_centerRads) * (_outR + 3), _textY = Math.sin(_centerRads) * (_outR + 3), _segments = []; + _repr.renderer.buttons_layer.activate(); var _path = new paper.Path(); _path.add([_startXIn, _startYIn]); _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]); @@ -261,14 +264,19 @@ } this.last_circle_radius = 1; this.title.paragraphStyle.justification = 'center'; + + this.renderer.minimap.node_layer.activate(); + this.minimap_circle = new paper.Path.Circle([0, 0], 1); + this.renderer.minimap.node_group.addChild(this.minimap_circle); } Rkns.Renderer.Node.prototype.redraw = function() { + var _model_coords = new paper.Point(this.model.get("position")), + _baseRadius = Rkns.Renderer._NODE_SIZE_BASE * Math.exp((this.model.get("size") || 0) * Rkns.Renderer._NODE_SIZE_STEP); if (!this.paper_coords) { - var _model_coords = new paper.Point(this.model.get("position")); this.paper_coords = this.renderer.toPaperCoords(_model_coords); } - this.circle_radius = Rkns.Renderer._NODE_SIZE_BASE * Math.exp((this.model.get("size") || 0) * Rkns.Renderer._NODE_SIZE_STEP) * this.renderer.scale; + this.circle_radius = _baseRadius * this.renderer.scale; if (this.last_circle_radius !== this.circle_radius) { if (!this.renderer.renkan.read_only) { this.edit_button.setSectorSize(); @@ -292,7 +300,8 @@ this.title.content = this.model.get("title") || this.renderer.renkan.translate("(untitled)"); this.title.position = this.paper_coords.add([0, this.circle_radius + 1.5 *Rkns.Renderer._NODE_FONT_SIZE]); - this.circle.strokeColor = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color"); + var _color = this.model.get("color") || (this.model.get("created_by") || Rkns.Renderer._USER_PLACEHOLDER).get("color"); + this.circle.strokeColor = _color; this.edit_button.moveTo(this.paper_coords); this.remove_button.moveTo(this.paper_coords); this.link_button.moveTo(this.paper_coords); @@ -330,6 +339,12 @@ this.node_image.remove(); delete this.node_image; } + + this.minimap_circle.fillColor = _color; + var minipos = this.renderer.toMinimapCoords(_model_coords), + miniradius = this.renderer.minimap.scale * _baseRadius, + minisize = new paper.Size([miniradius, miniradius]); + this.minimap_circle.fitBounds(minipos.subtract(minisize), minisize.multiply(2)); Rkns._.each(this.project.get("edges").filter(function (ed) { return ((ed.to === this.model) || (ed.from === this.model));}), function(edge, index, list){ var repr = this.renderer.getRepresentationByModel(edge); @@ -366,6 +381,7 @@ if (this.renderer.renkan.read_only) { this.openEditor(); } + this.minimap_circle.fillColor = "#ff00fc"; } Rkns.Renderer.Node.prototype.unselect = function(_newTarget) { @@ -375,6 +391,7 @@ this.link_button.hide(); this.circle.strokeWidth = 2; Rkns.$('.Rk-Bin-Item').removeClass("selected"); + this.minimap_circle.fillColor = this.circle.strokeColor; } } @@ -423,6 +440,7 @@ this.link_button.destroy(); this.circle.remove(); this.title.remove(); + this.minimap_circle.remove(); if (this.node_image) { this.node_image.remove(); } @@ -918,7 +936,6 @@ Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); Rkns.Renderer.NodeEditButton.prototype._init = function() { - this.renderer.buttons_layer.activate(); this.type = "Node-edit-button"; this.lastSectorInner = 0; } @@ -972,7 +989,6 @@ Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); Rkns.Renderer.NodeRemoveButton.prototype._init = function() { - this.renderer.buttons_layer.activate(); this.type = "Node-remove-button"; this.lastSectorInner = 0; } @@ -1027,7 +1043,6 @@ Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); Rkns.Renderer.NodeLinkButton.prototype._init = function() { - this.renderer.buttons_layer.activate(); this.type = "Node-link-button"; this.lastSectorInner = 0; } @@ -1075,7 +1090,6 @@ Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); Rkns.Renderer.EdgeEditButton.prototype._init = function() { - this.renderer.buttons_layer.activate(); this.type = "Edge-edit-button"; this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 90, 90, 1, this.renderer.renkan.static_url+'img/edit.png', this.renderer.renkan.translate("Edit")); } @@ -1118,7 +1132,6 @@ Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation); Rkns.Renderer.EdgeRemoveButton.prototype._init = function() { - this.renderer.buttons_layer.activate(); this.type = "Edge-remove-button"; this.sector = Rkns.Renderer.Utils.sector(this, Rkns.Renderer._EDGE_BUTTON_INNER, Rkns.Renderer._EDGE_BUTTON_OUTER, - 270, -90, 1, this.renderer.renkan.static_url+'img/remove.png', this.renderer.renkan.translate("Remove")); } @@ -1175,6 +1188,33 @@ this.edge_layer = new paper.Layer(); this.node_layer = new paper.Layer(); this.buttons_layer = new paper.Layer(); + + this.minimap = { + background_layer: new paper.Layer(), + node_layer: new paper.Layer(), + node_group: new paper.Group(), + size: new paper.Size( Rkns.Renderer._MINIMAP_WIDTH, Rkns.Renderer._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 = '#ffffff'; + this.minimap.rectangle.strokeColor = '#cccccc'; + this.minimap.rectangle.strokeWidth = 4; + this.minimap.offset = new paper.Point(this.minimap.size.divide(2)); + this.minimap.scale = .25; + + this.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 = '#f0f0ff'; + this.minimap.miniframe.strokeColor = '#8080ff'; + this.minimap.miniframe.strokeWidth = 2; + this.bundles = []; this.click_mode = false; var _tool = new paper.Tool(), @@ -1205,29 +1245,38 @@ this.canvas_$.on("drop", function(_event) { _event.stopPropagation(); _event.preventDefault(); + if (_this.renkan.read_only) { + return; + } var res = {} Rkns._(_event.originalEvent.dataTransfer.types).each(function(t) { return res[t] = _event.originalEvent.dataTransfer.getData(t); }); var newNode = {}; + if (res["text/x-iri-source-uri"]) { + newNode.uri = res["text/x-iri-source-uri"]; + } if (res["text/plain"]) { newNode.description = res["text/plain"].replace(/[\s\n]+/gm,' ').trim(); } if (res["text/html"]) { var snippet = Rkns.$('
    ').html(res["text/html"]); newNode.image = snippet.find("img").attr("src") || ''; - newNode.uri = snippet.find("a").attr("href"); + newNode.uri = snippet.find("a").attr("href") || newNode.uri; newNode.title = snippet.find("[title]").attr("title"); } if (res["text/uri-list"]) { newNode.uri = res["text/uri-list"]; } - if (res["text/x-moz-url"]) { + if (res["text/x-moz-url"] && !newNode.title) { newNode.title = (res["text/x-moz-url"].split("\n")[1] || "").trim(); if (newNode.title === newNode.uri) { - newNode.title = ""; + newNode.title = false; } } + if (res["text/x-iri-source-title"] && !newNode.title) { + newNode.title = res["text/x-iri-source-title"]; + } var fields = ["title", "description", "uri", "image"]; for (var i = 0; i < fields.length; i++) { var f = fields[i]; @@ -1307,7 +1356,7 @@ _this.notif_$.hide(); } else { _this.click_mode = Rkns.Renderer._CLICKMODE_ADDNODE; - _this.notif_$.html(_renkan.translate("Click on the background canvas to add a node")).fadeIn(); + _this.notif_$.text(_renkan.translate("Click on the background canvas to add a node")).fadeIn(); } }); this.$.find(".Rk-AddEdge-Button").click(function() { @@ -1316,9 +1365,17 @@ _this.notif_$.hide(); } else { _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE; - _this.notif_$.html(_renkan.translate("Click on a first node to start the edge")).fadeIn(); + _this.notif_$.text(_renkan.translate("Click on a first node to start the edge")).fadeIn(); } }); + this.$.find(".Rk-Bookmarklet-Button").click(function(){ + _this.notif_$ + .text(_renkan.translate("Drag this bookmarklet 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() { @@ -1328,6 +1385,9 @@ paper.view.onResize = function(_event) { _this.offset = _this.offset.add(_event.delta.divide(2)); _this.resetCoords(); + _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(); } @@ -1372,6 +1432,9 @@ }); this.redraw(); + window.setInterval(function() { + _this.rescaleMinimap() + }, 2000); } Rkns.Renderer.Scene.prototype.template = Rkns._.template( @@ -1383,6 +1446,10 @@ + '
    <%-translate("Add Node")%>
    ' + '
    <%-translate("Add Edge")%>
    ' + '
    <%-translate("Archive Project")%>
    ' + + '
    ' + + '<%-translate("Renkan \'Drag and Add\' bookmarklet")%>
    ' + '
    ' + '<% } %>' + '
    ' @@ -1419,8 +1486,14 @@ this.resetCoords(); this.redraw(); } -/* -Rkns.Renderer.Scene.prototype.autoScale = function() { + +Rkns.Renderer.Scene.prototype.redrawMiniframe = function() { + var topleft = this.toMinimapCoords(this.toModelCoords(new paper.Point([0,0]))), + bottomright = this.toMinimapCoords(this.toModelCoords(paper.view.bounds.bottomRight)); + this.minimap.miniframe.fitBounds(topleft, bottomright); +} + +Rkns.Renderer.Scene.prototype.rescaleMinimap = function() { var nodes = this.renkan.project.get("nodes") if (nodes.length > 1) { var _xx = nodes.map(function(_node) { return _node.get("position").x }), @@ -1429,16 +1502,17 @@ _miny = Math.min.apply(Math, _yy), _maxx = Math.max.apply(Math, _xx), _maxy = Math.max.apply(Math, _yy); - var _scale = Math.min((paper.view.size.width - 2 * Rkns.Renderer._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * Rkns.Renderer._MARGIN_Y) / (_maxy - _miny)); - this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)); - this.setScale(_scale); + var _scale = Math.min(this.scale * .8 * Rkns.Renderer._MINIMAP_WIDTH / paper.view.bounds.width, this.scale * .8 * Rkns.Renderer._MINIMAP_HEIGHT / paper.view.bounds.height, (Rkns.Renderer._MINIMAP_WIDTH - 2 * Rkns.Renderer._MINIMAP_MARGIN_X) / (_maxx - _minx), (Rkns.Renderer._MINIMAP_HEIGHT - 2 * Rkns.Renderer._MINIMAP_MARGIN_Y) / (_maxy - _miny)); + this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale)); + this.minimap.scale = _scale; } if (nodes.length === 1) { - this.offset = paper.view.center.subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y])); - this.setScale(1); + this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y])); + this.minimap.scale = .25; } + this.redraw(); } -*/ + Rkns.Renderer.Scene.prototype.resetCoords = function(_point) { _(this.representations).each(function(r) { r.resetCoords(); @@ -1449,6 +1523,9 @@ return _point.multiply(this.scale).add(this.offset); } +Rkns.Renderer.Scene.prototype.toMinimapCoords = function(_point) { + return _point.multiply(this.minimap.scale).add(this.minimap.offset).add(this.minimap.topleft); +} Rkns.Renderer.Scene.prototype.toModelCoords = function(_point) { return _point.subtract(this.offset).divide(this.scale); @@ -1529,6 +1606,7 @@ Rkns._(this.representations).each(function(_representation) { _representation.redraw(); }); + this.redrawMiniframe(); paper.view.draw(); }