Add Edge button, French translation and various bugfixes
authorveltr
Wed, 05 Sep 2012 14:49:33 +0200
changeset 36 d249d36ecc37
parent 35 10e0c23c849e
child 37 db991a757015
Add Edge button, French translation and various bugfixes
client/css/renkan.css
client/img/topbarbuttons.png
client/js/full-json.js
client/js/i18n.js
client/js/main.js
client/js/paper-renderer.js
client/js/twitter-bin.js
client/js/wikipedia-bin.js
client/render-test.html
--- a/client/css/renkan.css	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/css/renkan.css	Wed Sep 05 14:49:33 2012 +0200
@@ -138,6 +138,14 @@
 .Rk-FullScreen-Button:hover {
     background-position: -34px -35px;
 }
+
+.Rk-AddEdge-Button {
+    width: 34px; background-position: -68px 0;
+}
+
+.Rk-AddEdge-Button:hover {
+    background-position: -68px -35px;
+}
 /* Canvas */
 
 .Rk-Canvas {
@@ -149,7 +157,16 @@
 /* Editors */
 
 .Rk-Editor {
-    position: absolute; left: 0; top: 35px; z-index: 2;
+    position: absolute; left: 0; top: 35px; right: 0; z-index: 2;
+}
+
+.Rk-Notifications {
+    position: absolute; right: 15px; top: 15px; width: 200px;
+    padding: 10px; border-radius: 8px; display: none;
+    color: #ffffff; font-size: 13px; text-align: center; font-weight: bold;
+    background: rgba(20,20,20,.7);
+    background: -moz-linear-gradient(top, rgba(40,40,40,.7) 20%, rgba(0,0,0,.7) 80%);
+    background: -webkit-linear-gradient(top, rgba(40,40,40,.7) 20%, rgba(0,0,0,.7) 80%);
 }
 
 .Rk-CloseX {
@@ -264,13 +281,14 @@
 }
 
 .Rk-Search-Current {
-    width: 25px; height: 20px; margin: 2px;
+    width: 40px; height: 20px; margin: 2px; background-repeat: no-repeat;
 }
 
 .Rk-Search-List {
-    width: 160px; margin-left: 15px; font-size: 13px;
-    position: absolute; left: -75px; top: 25px; background: #ffffff;
-    box-shadow: 0 1px 0 #505050; display: none;
+    width: 180px; margin-left: 15px; font-size: 13px;
+    position: absolute; right: 0; top: 25px; background: #ffffff;
+    box-shadow: 1px 1px 2px #505050; display: none;
+    border: 1px solid #cccccc;
 }
 
 .Rk-Search-List li {
@@ -284,7 +302,7 @@
 
 .Rk-Search-Submit {
     border: 1px solid #003050; height: 27px; width: 30px; border-top-right-radius: 5px; border-bottom-right-radius: 5px;
-    background: #333333 center no-repeat url(../img/search.png);
+    background: #333333 center no-repeat url(../img/search.png); cursor: pointer;
 }
 
 .Rk-Search-Submit:hover {
Binary file client/img/topbarbuttons.png has changed
--- a/client/js/full-json.js	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/js/full-json.js	Wed Sep 05 14:49:33 2012 +0200
@@ -32,5 +32,6 @@
         _model.on("change remove", function(_model) {
             _thrSave();
         });
+        _thrSave();
     });
 }
--- a/client/js/i18n.js	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/js/i18n.js	Wed Sep 05 14:49:33 2012 +0200
@@ -9,8 +9,42 @@
         edit_to: "To:",
         full_screen: "Full Screen",
         add_node: "Add Node",
+        add_edge: "Add Edge",
         created_by: "Created by:",
         zoom_in: "Zoom In",
-        zoom_out: "Zoom Out"
+        zoom_out: "Zoom Out",
+        notif_add_node: "Click on the background canvas to add a node",
+        notif_start_edge: "Click on a first node to start the edge",
+        notif_end_edge: "Click on a second node to complete the edge",
+        search_on_twitter: "Twitter",
+        wiki_fr: "French Wikipedia",
+        wiki_en: "English Wikipedia",
+        wiki_ja: "Japanese Wikipedia",
+        wiki_: "Wikipedia (Other Language)",
+        untitled_project: "Untitled project"
+    },
+    fr: {
+        edit_node: "Édition d’un nœud",
+        edit_edge: "Édition d’un lien",
+        edit_title: "Titre:",
+        edit_uri: "URI:",
+        edit_description: "Description :",
+        edit_from: "De:",
+        edit_to: "Vers:",
+        full_screen: "Mode plein écran",
+        add_node: "Ajouter un nœud",
+        add_edge: "Ajouter un lien",
+        created_by: "Créé par :",
+        zoom_in: "Agrandir l’échelle",
+        zoom_out: "Rapetisser l’échelle",
+        notif_add_node: "Cliquer sur le fond du graphe pour rajouter un nœud",
+        notif_start_edge: "Cliquer sur un premier nœud pour commencer le lien",
+        notif_end_edge: "Cliquer sur un second nœud pour terminer le lien",
+        search_on_twitter: "Twitter",
+        wiki_fr: "Wikipedia en Français",
+        wiki_en: "Wikipedia en Anglais",
+        wiki_ja: "Wikipedia en Japonais",
+        wiki_: "Wikipedia (Autre langue)",
+        untitled_project: "Projet sans titre"
     }
 }
--- a/client/js/main.js	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/js/main.js	Wed Sep 05 14:49:33 2012 +0200
@@ -123,11 +123,12 @@
             }
             return false;
         });
-        this.$.find(".Rk-Search-Select").mouseenter(function() {
-            _select.slideDown();
-        }).mouseleave(function() {
-            _select.slideUp();
-        })
+        this.$.find(".Rk-Search-Current").mouseenter(
+            function() { _select.slideDown(); }
+        );
+        this.$.find(".Rk-Search-Select").mouseleave(
+            function() { _select.slideUp(); }
+        );
         this.setSearchEngine(0);
     }
     Rkns._(_opts.bins).each(function(_bin) {
--- a/client/js/paper-renderer.js	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/js/paper-renderer.js	Wed Sep 05 14:49:33 2012 +0200
@@ -17,7 +17,10 @@
     _EDITOR_ARROW_WIDTH : 40,
     _EDITOR_MARGIN : 15,
     _EDITOR_PADDING : 10,
-    _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0'])
+    _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0']),
+    _CLICKMODE_ADDNODE : 1,
+    _CLICKMODE_STARTEDGE : 2,
+    _CLICKMODE_ENDEDGE : 3
 }
 
 Rkns.Renderer.Utils = {
@@ -272,6 +275,8 @@
     if (!this.renderer.is_dragging) {
         this.openEditor();
     }
+    this.renderer.click_target = null;
+    this.renderer.is_dragging = false;
 }
 
 Rkns.Renderer.Node.prototype.destroy = function(_event) {
@@ -376,6 +381,8 @@
     if (!this.renderer.is_dragging) {
         this.openEditor();
     }
+    this.renderer.click_target = null;
+    this.renderer.is_dragging = false;
 }
 
 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
@@ -436,20 +443,31 @@
 }
 
 Rkns.Renderer.TempEdge.prototype.mouseup = function(_event) {
-    var _hitResult = paper.project.hitTest(_event.point);
+    var _hitResult = paper.project.hitTest(_event.point),
+        _model = this.from_representation.model,
+        _endDrag = true;
     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
         var _target = _hitResult.item.__representation;
-        if (_target.type === "Node" && this.from_representation.model !== _target.model) {
+        if (_target.type === "Node" && _model !== _target.model) {
             var _data = {
                 id: Rkns.Utils.getUID('edge'),
                 created_by: this.renderer.renkan.current_user,
-                from: this.from_representation.model.get("_id"),
+                from: _model.get("_id"),
                 to: _target.model.get("_id")
             };
             this.project.addEdge(_data);
         }
+        if (_model === _target.model || (_target.node_representation && _target.node_representation.model === _model)) {
+            _endDrag = false;
+            this.renderer.is_dragging = true;
+        }
     }
-    this.renderer.removeRepresentation(this);
+    if (_endDrag) {
+        this.renderer.click_target = null;
+        this.renderer.is_dragging = false;
+        this.renderer.removeRepresentation(this);
+        paper.view.draw();
+    }
 }
 
 Rkns.Renderer.TempEdge.prototype.destroy = function() {
@@ -679,6 +697,7 @@
 }
 
 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
+    this.renderer.removeRepresentationsOfType("editor");
     if (confirm('Do you really wish to remove node "' + this.node_representation.model.get("title") + '"?')) {
         this.project.removeNode(this.node_representation.model);
     }
@@ -801,6 +820,7 @@
 }
 
 Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
+    this.renderer.removeRepresentationsOfType("editor");
     if (confirm('Do you really wish to remove edge "' + this.edge_representation.model.get("title") + '"?')) {
         this.project.removeEdge(this.edge_representation.model);
     }
@@ -821,6 +841,7 @@
     }))
     this.canvas_$ = this.$.find(".Rk-Canvas");
     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;
@@ -831,6 +852,7 @@
     this.node_layer = new paper.Layer();
     this.overlay_layer = new paper.Layer();
     this.bundles = [];
+    this.click_mode = false;
     var _tool = new paper.Tool(),
         _this = this;
     _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
@@ -871,11 +893,12 @@
         _this.setScale( _this.scale * Math.SQRT2 );
         _this.redraw();
     });
-    this.$.find(".Rk-Users").mouseenter(function() {
-        _this.$.find(".Rk-UserList").slideDown();
-    }).mouseleave(function() {
-        _this.$.find(".Rk-UserList").slideUp();
-    });
+    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],
@@ -898,17 +921,22 @@
         }
     });
     this.$.find(".Rk-AddNode-Button").click(function() {
-        var _coords = _this.toModelCoords(paper.view.center),
-            _data = {
-                id: Rkns.Utils.getUID('node'),
-                created_by: _this.renkan.current_user,
-                position: {
-                    x: _coords.x,
-                    y: _coords.y
-                }
-            };
-            _node = _this.renkan.project.addNode(_data);
-        _this.getRepresentationByModel(_node).openEditor();
+        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_$.html(_renkan.l10n.notif_add_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_$.html(_renkan.l10n.notif_start_edge).fadeIn();
+        }
     });
     this.$.find(".Rk-TopBar-Button").mouseover(function() {
         Rkns.$(this).find(".Rk-TopBar-Tooltip").show();
@@ -947,12 +975,13 @@
 }
 
 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
-    '<div class="Rk-TopBar"><h3 class="Rk-PadTitle">Untitled Project</h3>'
+    '<div class="Rk-TopBar"><h3 class="Rk-PadTitle"><%=l10n.untitled_project%></h3>'
     + '<div class="Rk-Users"><div class="Rk-CurrentUser"><span class="Rk-CurrentUser-Color"></span><span class="Rk-CurrentUser-Name">&lt;unknown user&gt;</span></div><ul class="Rk-UserList"></ul></div>'
     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-FullScreen-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%=l10n.full_screen%></div></div></div>'
     + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddNode-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%=l10n.add_node%></div></div></div>'
+    + '<div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddEdge-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Tip"></div><div class="Rk-TopBar-Tooltip-Contents"><%=l10n.add_edge%></div></div></div>'
     + '<div class="Rk-TopBar-Separator"></div></div>'
-    + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor">'
+    + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
     + '</div>'
 );
@@ -1138,18 +1167,44 @@
 }
 
 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
-    this.is_dragging = false;
-    var _hitResult = paper.project.hitTest(_event.point);
-    if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
-        this.click_target = _hitResult.item.__representation;
-        if (this.click_target.type === "Node" && _hitResult.type === "stroke") {
+    if (!this.click_target || this.click_target.type !== "temp-edge") {
+        this.is_dragging = false;
+        var _hitResult = paper.project.hitTest(_event.point);
+        if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
+            this.click_target = _hitResult.item.__representation;
+            if (this.click_target.type === "Node-link-button") {
+                this.removeRepresentationsOfType("editor");
+                this.addTempEdge(this.click_target.node_representation, _event.point);
+            }
+        } else {
+            this.click_target = null;
+            if (this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
+                var _coords = this.toModelCoords(_event.point),
+                    _data = {
+                        id: Rkns.Utils.getUID('node'),
+                        created_by: this.renkan.current_user,
+                        position: {
+                            x: _coords.x,
+                            y: _coords.y
+                        }
+                    };
+                    _node = this.renkan.project.addNode(_data);
+                this.getRepresentationByModel(_node).openEditor();
+            }
+        }
+    }
+    if (this.click_mode) {
+        if (this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === "Node") {
+            this.removeRepresentationsOfType("editor");
             this.addTempEdge(this.click_target, _event.point);
+            this.click_mode = Rkns.Renderer._CLICKMODE_ENDEDGE;
+            this.notif_$.fadeOut(function() {
+                Rkns.$(this).html(_renkan.l10n.notif_end_edge).fadeIn();
+            });
+        } else {
+            this.notif_$.hide();
+            this.click_mode = false;
         }
-        if (this.click_target.type === "Node-link-button") {
-            this.addTempEdge(this.click_target.node_representation, _event.point);
-        }
-    } else {
-        this.click_target = null;
     }
 }
 
@@ -1169,9 +1224,10 @@
                 ])
             }
         );
+    } else {
+        this.click_target = null;
+        this.is_dragging = false;
     }
-    this.is_dragging = false;
-    this.click_target = null;
 }
 
 Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) {
--- a/client/js/twitter-bin.js	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/js/twitter-bin.js	Wed Sep 05 14:49:33 2012 +0200
@@ -1,9 +1,4 @@
 Rkns.Twitter = {
-	i18n: {
-		en: {
-			search_on_twitter: "Twitter"
-		}
-	}
 }
 
 Rkns.Twitter.Search = function(_renkan, _opts) {
@@ -16,8 +11,7 @@
 }
 
 Rkns.Twitter.Search.prototype.getSearchTitle = function() {
-	var _lang = Rkns.Twitter.i18n[this.renkan.lang] || Rkns.Twitter.i18n['en'];
-	return _lang.search_on_twitter;
+	return this.renkan.l10n.search_on_twitter;
 }
 
 Rkns.Twitter.Search.prototype.search = function(_q) {
@@ -45,7 +39,6 @@
 
 Rkns.Twitter.Bin.prototype._init = function(_renkan, _opts) {
     this.search = _opts.search;
-    var _lang = Rkns.Twitter.i18n[this.renkan.lang] || Rkns.Twitter.i18n['en'];
     this.title_icon_$.addClass('Rk-Twitter-Title-Icon');
     this.title_$.html(this.search).addClass("Rk-Twitter-Title");
     var _this = this;
--- a/client/js/wikipedia-bin.js	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/js/wikipedia-bin.js	Wed Sep 05 14:49:33 2012 +0200
@@ -1,12 +1,4 @@
 Rkns.Wikipedia = {
-    i18n: {
-        en: {
-            wiki_fr: "French Wikipedia",
-            wiki_en: "English Wikipedia",
-            wiki_ja: "Japanese Wikipedia",
-            wiki_: "Wikipedia (Other Language)"
-        }
-    }
 }
 
 Rkns.Wikipedia.Search = function(_renkan, _opts) {
@@ -19,8 +11,7 @@
 }
 
 Rkns.Wikipedia.Search.prototype.getSearchTitle = function() {
-    var _lang = Rkns.Wikipedia.i18n[this.renkan.lang] || Rkns.Wikipedia.i18n['en'];
-    return ( _lang["wiki_" + this.lang] || _lang.wiki_) ;
+    return ( this.renkan.l10n["wiki_" + this.lang] || this.renkan.l10n.wiki_) ;
 }
 
 Rkns.Wikipedia.Search.prototype.search = function(_q) {
@@ -44,7 +35,6 @@
 Rkns.Wikipedia.Bin.prototype._init = function(_renkan, _opts) {
     this.search = _opts.search;
     this.lang = _opts.lang || "en";
-    var _lang = Rkns.Wikipedia.i18n[this.renkan.lang] || Rkns.Wikipedia.i18n['en'];
     this.title_icon_$.addClass('Rk-Wikipedia-Title-Icon Rk-Wikipedia-Lang-' + this.lang);
     this.title_$.html(this.search).addClass("Rk-Wikipedia-Title");
     var _this = this;
--- a/client/render-test.html	Mon Sep 03 18:51:32 2012 +0200
+++ b/client/render-test.html	Wed Sep 05 14:49:33 2012 +0200
@@ -25,6 +25,7 @@
             var _proj;
             $(function() {
                 _renkan = new Rkns.Renkan({
+                    language: "fr",
                     url: "data/simple-persist.php",
                     bins: [
                         {