Merge with f21792c7b0ab2928e5e7a7c10dff8dde78c0f39e
authorymh <ymh.work@gmail.com>
Thu, 16 Aug 2012 16:01:49 +0200
changeset 14 f7d9fe3ef6f3
parent 13 6d0e0100f4e8 (current diff)
parent 12 f21792c7b0ab (diff)
child 16 399690e161cc
Merge with f21792c7b0ab2928e5e7a7c10dff8dde78c0f39e
client/js/json-serializer.js
--- a/client/css/renkan.css	Thu Aug 16 15:59:25 2012 +0200
+++ b/client/css/renkan.css	Thu Aug 16 16:01:49 2012 +0200
@@ -72,24 +72,23 @@
 .Rk-UserColor {
     display: inline-block; width: 1em; height: 1em; border: 1px solid #666666; margin: -2px 2px;
 }
-/*
-.Rk-Button-Edit, .Rk-Button-Remove {
-    width: 67px; height: 134px; background: url("../img/remove-edit.png");
+
+.Rk-ZoomButtons {
+    position: absolute; left: 0; top: 0; cursor: pointer;
 }
 
-.Rk-Button-Edit {
-    background-position: -67px -134px;
+.Rk-ZoomIn, .Rk-ZoomOut {
+    width: 21px; height: 20px; background: url(../img/zoombuttons.png); margin: 5px;
 }
 
-.Rk-Button-Edit:hover {
-    background-position: -67px 0;
+.Rk-ZoomIn:hover {
+    background-position: 0 -20px;
 }
 
-.Rk-Button-Remove {
-    background-position: 0 -134px;
+.Rk-ZoomOut {
+    background-position: -21px 0;
 }
 
-.Rk-Button-Remove:hover {
-    background-position: -67px 0;
-}
-*/
\ No newline at end of file
+.Rk-ZoomOut:hover {
+    background-position: -21px -20px;
+}
\ No newline at end of file
--- a/client/data/dynamic-data.json	Thu Aug 16 15:59:25 2012 +0200
+++ b/client/data/dynamic-data.json	Thu Aug 16 16:01:49 2012 +0200
@@ -1,1 +1,1 @@
-{"title":"Test Graph","users":[{"id":"anonymous","title":"anonymous","uri":"","color":"#0000ff"},{"id":"u-cybunk","title":"Samuel","uri":"http://twitter.com/cybunk","color":"#e00000"},{"id":"u-raphv","title":"Raphael","uri":"http://twitter.com/raphv","color":"#00a000"}],"nodes":[{"id":"n-001","title":"連環 (Renkan)","uri":"http://ja.wikipedia.org/wiki/%E7%99%BE%E5%AD%A6%E9%80%A3%E7%92%B0","created_by":"u-cybunk","position":{"x":-25.88895000000003,"y":87.51464999999999}},{"id":"n-002","title":"Savoir","uri":"http://fr.wikipedia.org/wiki/Savoir","created_by":"u-raphv","position":{"x":188.95000000000002,"y":96.14999999999998}},{"id":"n-003","title":"Connaissance","uri":"http://fr.wikipedia.org/wiki/Connaissance","created_by":"u-raphv","position":{"x":289.4208034783762,"y":-126.35817503078205}},{"id":"n-004","title":"graphe","uri":"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes","created_by":"u-cybunk","position":{"x":-255.49131419301492,"y":14.045175554077602}},{"id":"n-005","title":"nœud","uri":"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes","created_by":"u-cybunk","position":{"x":"-350","y":"100"}},{"id":"n-006","title":"lien","uri":"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes","created_by":"u-cybunk","position":{"x":"-300","y":"-100"}},{"id":"node-2012-07-30-228fe77f55e6c8cb-000c","title":"Tree of Knowledge","uri":"","created_by":"anonymous","position":{"x":16.731250153910498,"y":-33.2191000923462}},{"id":"node-2012-07-30-228fe77f55e6c8cb-0019","title":"Tree (木)","uri":"","created_by":"anonymous","position":{"x":-65.06465000000001,"y":-117.73549999999994}},{"id":"node-2012-07-30-9b22dc180265ecd3-0018","title":"(untitled node)","uri":"","created_by":"anonymous","position":{"x":-209.8383754309492,"y":-95.79672580033416}}],"edges":[{"id":"e-001","title":"(untitled edge)","description":"","uri":"","from":"n-001","to":"n-002","created_by":"u-raphv"},{"id":"e-002","title":"(untitled edge)","description":"","uri":"","from":"n-002","to":"n-003","created_by":"u-raphv"},{"id":"e-003","title":"(untitled edge)","description":"","uri":"","from":"n-001","to":"n-004","created_by":"u-cybunk"},{"id":"e-004","title":"(untitled edge)","description":"","uri":"","from":"n-004","to":"n-005","created_by":"u-cybunk"},{"id":"e-005","title":"(untitled edge)","description":"","uri":"","from":"n-004","to":"n-006","created_by":"u-cybunk"},{"id":"edge-2012-07-30-228fe77f55e6c8cb-0010","title":"(untitled edge)","description":"","uri":"","from":"node-2012-07-30-228fe77f55e6c8cb-000c","to":"n-001","created_by":"anonymous"},{"id":"edge-2012-07-30-228fe77f55e6c8cb-0013","title":"arête sans titre","description":"","uri":"","from":"node-2012-07-30-228fe77f55e6c8cb-000c","to":"n-003","created_by":"anonymous"},{"id":"edge-2012-07-30-228fe77f55e6c8cb-0016","title":"Similarité","description":"","uri":"","from":"n-004","to":"node-2012-07-30-228fe77f55e6c8cb-000c","created_by":"anonymous"},{"id":"edge-2012-07-30-228fe77f55e6c8cb-001d","title":"(untitled edge)","description":"","uri":"","from":"node-2012-07-30-228fe77f55e6c8cb-0019","to":"node-2012-07-30-228fe77f55e6c8cb-000c","created_by":"anonymous"}]}
\ No newline at end of file
+{"title":"Test Graph","users":[{"id":"anonymous","title":"anonymous","uri":"","color":"#0000ff"},{"id":"u-cybunk","title":"Samuel","uri":"http://twitter.com/cybunk","color":"#e00000"},{"id":"u-raphv","title":"Raphael","uri":"http://twitter.com/raphv","color":"#00a000"}],"nodes":[{"id":"n-001","title":"連環 (Renkan)","description":"Vive Renkan !","uri":"http://ja.wikipedia.org/wiki/%E7%99%BE%E5%AD%A6%E9%80%A3%E7%92%B0","created_by":"u-cybunk","position":{"x":-26.522137994214717,"y":-210.84128058998363}},{"id":"n-002","title":"Savoir","description":"","uri":"http://fr.wikipedia.org/wiki/Savoir","created_by":"u-raphv","position":{"x":51.05688741877592,"y":2.5968600661189982}},{"id":"n-003","title":"Connaissance","description":"","uri":"http://fr.wikipedia.org/wiki/Connaissance","created_by":"u-raphv","position":{"x":289.41278995919333,"y":-148.06006021345246}},{"id":"n-005","title":"nœud","description":"","uri":"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes","created_by":"u-cybunk","position":{"x":-348.6577736928668,"y":36.915363564739906}},{"id":"n-006","title":"arête","description":"","uri":"http://fr.wikipedia.org/wiki/Th%C3%A9orie_des_graphes","created_by":"u-cybunk","position":{"x":-310.04965494954644,"y":-269.5988072780878}},{"id":"node-2012-07-31-f1c2d0fd52a9d0e2-0016","title":"graphe","description":"","uri":"","created_by":"anonymous","position":{"x":-190.13786466320713,"y":-97.7768211544552}},{"id":"node-2012-07-31-6d574a0c9d5d2931-0026","title":"Test","description":"","uri":"","created_by":"anonymous","position":{"x":156.5765089679022,"y":-297.9314037374282}}],"edges":[{"id":"e-001","title":"(untitled edge)","uri":"","from":"n-001","to":"n-002","created_by":"u-raphv"},{"id":"e-002","title":"(untitled edge)","uri":"","from":"n-002","to":"n-003","created_by":"u-raphv"},{"id":"edge-2012-07-31-f1c2d0fd52a9d0e2-0013","title":"(untitled edge)","uri":"","from":"n-006","to":"n-001","created_by":"anonymous"},{"id":"edge-2012-07-31-f1c2d0fd52a9d0e2-001d","title":"(untitled edge)","uri":"","from":"node-2012-07-31-f1c2d0fd52a9d0e2-0016","to":"n-005","created_by":"anonymous"},{"id":"edge-2012-07-31-f1c2d0fd52a9d0e2-0020","title":"(untitled edge)","uri":"","from":"node-2012-07-31-f1c2d0fd52a9d0e2-0016","to":"n-001","created_by":"anonymous"},{"id":"edge-2012-07-31-f1c2d0fd52a9d0e2-0023","title":"(untitled edge)","uri":"","from":"node-2012-07-31-f1c2d0fd52a9d0e2-0016","to":"n-006","created_by":"anonymous"},{"id":"edge-2012-07-31-6d574a0c9d5d2931-002c","title":"(untitled edge)","uri":"","from":"node-2012-07-31-6d574a0c9d5d2931-0026","to":"n-001","created_by":"anonymous"}]}
\ No newline at end of file
Binary file client/img/edit.png has changed
Binary file client/img/link.png has changed
Binary file client/img/remove.png has changed
Binary file client/img/zoombuttons.png has changed
--- a/client/js/i18n.js	Thu Aug 16 15:59:25 2012 +0200
+++ b/client/js/i18n.js	Thu Aug 16 16:01:49 2012 +0200
@@ -7,6 +7,8 @@
         edit_description: "Description:",
         edit_from: "From:",
         edit_to: "To:",
-        created_by: "Created by:"
+        created_by: "Created by:",
+        zoom_in: "Zoom In",
+        zoom_out: "Zoom Out"
     }
 }
--- a/client/js/json-serializer.js	Thu Aug 16 15:59:25 2012 +0200
+++ b/client/js/json-serializer.js	Thu Aug 16 16:01:49 2012 +0200
@@ -79,6 +79,7 @@
             return {
                 id: _node.id,
                 title: _node.title,
+                description: _node.description,
                 uri: _node.uri,
                 created_by: _node.created_by.id,
                 position: {
@@ -87,15 +88,14 @@
                 }
             }
         }),
-        edges: this._project.edges.map(function(_node) {
+        edges: this._project.edges.map(function(_edge) {
             return {
-                id: _node.id,
-                title: _node.title,
-                description: _node.description,
-                uri: _node.uri,
-                from: _node.from.id,
-                to: _node.to.id,
-                created_by: _node.created_by.id
+                id: _edge.id,
+                title: _edge.title,
+                uri: _edge.uri,
+                from: _edge.from.id,
+                to: _edge.to.id,
+                created_by: _edge.created_by.id
             }
         })
     }
--- a/client/js/paper-renderer.js	Thu Aug 16 15:59:25 2012 +0200
+++ b/client/js/paper-renderer.js	Thu Aug 16 16:01:49 2012 +0200
@@ -149,6 +149,8 @@
     this.edit_button.node_controller = this;
     this.remove_button = new Rkns.Renderer.NodeRemoveButton(this._renderer, {});
     this.remove_button.node_controller = this;
+    this.link_button = new Rkns.Renderer.NodeLinkButton(this._renderer, {});
+    this.link_button.node_controller = this;
     this.title.paragraphStyle.justification = 'center';
     this.title.__controller = this;
 }
@@ -162,6 +164,7 @@
     this.circle.strokeColor = this._element.created_by.color;
     this.edit_button.moveTo(this.paper_coords);
     this.remove_button.moveTo(this.paper_coords);
+    this.link_button.moveTo(this.paper_coords);
 }
 
 Rkns.Renderer.Node.prototype.paperShift = function(_delta) {
@@ -187,12 +190,14 @@
     this.circle.strokeWidth = 3;
     this.edit_button.show();
     this.remove_button.show();
+    this.link_button.show();
 }
 
 Rkns.Renderer.Node.prototype.unselect = function(_newTarget) {
-    if (!_newTarget || (_newTarget !== this.edit_button && _newTarget !== this.remove_button)) {
+    if (!_newTarget || (_newTarget !== this.edit_button && _newTarget !== this.remove_button && _newTarget !== this.link_button)) {
         this.edit_button.hide();
         this.remove_button.hide();
+        this.link_button.hide();
     }
     this.circle.strokeWidth = 1;
 }
@@ -361,7 +366,7 @@
     this.editor_block.fillColor = "#e0e0e0";
     this.editor_block.opacity = .8;
     this.editor_$ = Rkns.$('<div>')
-        .appendTo('.Rk-Editor')
+        .appendTo(this._renderer.editor_$)
         .css({
             position: "absolute",
             opacity: .8
@@ -430,7 +435,7 @@
     this.editor_block.fillColor = "#e0e0e0";
     this.editor_block.opacity = .8;
     this.editor_$ = Rkns.$('<div>')
-        .appendTo('.Rk-Editor')
+        .appendTo(this._renderer.editor_$)
         .css({
             position: "absolute",
             opacity: .8
@@ -517,6 +522,7 @@
     this.sector.group.opacity = .5;
     this.hide();
     this.node_controller.remove_button.hide();
+    this.node_controller.link_button.hide();
 }
 
 Rkns.Renderer.NodeEditButton.prototype.mouseup = function() {
@@ -563,10 +569,13 @@
     this.sector.group.opacity = .5;
     this.hide();
     this.node_controller.edit_button.hide();
+    this.node_controller.link_button.hide();
 }
 
 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
-    this._renderer._project.removeNode(this.node_controller._element, Rkns._RENDER_AND_SAVE)
+    if (confirm('Do you really wish to remove node "' + this.node_controller._element.title + '"?')) {
+        this._renderer._project.removeNode(this.node_controller._element, Rkns._RENDER_AND_SAVE);
+    }
 }
 
 Rkns.Renderer.NodeRemoveButton.prototype.destroy = function() {
@@ -575,12 +584,57 @@
 
 /* */
 
+Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._BaseController);
+
+Rkns.Renderer.NodeLinkButton.prototype._init = function() {
+    this._renderer.node_layer.activate();
+    this.type = "node-link-button";
+    this.sector = Rkns.Renderer.Utils.sector(1 + Rkns._NODE_RADIUS, 3 * Rkns._NODE_RADIUS, 30, 150, 2, 'img/link.png');
+    this.sector.group.visible = false;
+    this.sector.group.opacity = .5;
+    this.sector.circle.__controller = this;
+    this.sector.delta = this.sector.group.position;
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
+    this.sector.group.position = this.sector.delta.add(_pos);
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.show = function() {
+    this.sector.group.visible = true;
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.hide = function() {
+    this.sector.group.visible = false;
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.select = function() {
+    this.sector.group.opacity = .8;
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.unselect = function() {
+    this.sector.group.opacity = .5;
+    this.hide();
+    this.node_controller.edit_button.hide();
+    this.node_controller.remove_button.hide();
+}
+
+Rkns.Renderer.NodeLinkButton.prototype.destroy = function() {
+    this.sector.group.remove();
+}
+
+/* */
+
 Rkns.Renderer.Scene = function(_project) {
     this._project = _project;
     this._MARGIN_X = 80;
     this._MARGIN_Y = 50;
     var _canvas_id = this._project._opts.canvas_id;
-    this.$ = Rkns.$("#"+_canvas_id)
+    this.$ = Rkns.$("#"+_canvas_id);
+    this.editor_$ = Rkns.$(".Rk-Editor");
+    this.editor_$.html(this.editorTemplate({
+        l10n: this._project.l10n
+    }));
     paper.setup(document.getElementById(_canvas_id));
     this.scale = 1;
     this.offset = paper.view.center;
@@ -610,13 +664,33 @@
     })
     this.$.dblclick(function(_event) {
         _this.onDoubleClick(_event);
-    })
+    });
+    this.editor_$.find(".Rk-ZoomOut").click(function() {
+        _this.offset = new paper.Point([
+            _this.$.width(),
+            _this.$.height()
+        ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 ));
+        _this.scale *= Math.SQRT1_2;
+        _this.redraw();
+    });
+    this.editor_$.find(".Rk-ZoomIn").click(function() {
+        _this.offset = new paper.Point([
+            _this.$.width(),
+            _this.$.height()
+        ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
+        _this.scale *= Math.SQRT2;
+        _this.redraw();
+    });
     paper.view.onResize = function(_event) {
         _this.offset = _this.offset.add(_event.delta.divide(2));
         _this.redraw();
     }
 }
 
+Rkns.Renderer.Scene.prototype.editorTemplate = Rkns._.template(
+    '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
+);
+
 Rkns.Renderer.Scene.prototype.toPaperCoords = function(_point) {
     return _point.multiply(this.scale).add(this.offset);
 }
@@ -675,6 +749,14 @@
     paper.view.draw();
 }
 
+Rkns.Renderer.Scene.prototype.addTempEdge = function(_from, _point) {
+    var _tmpEdge = this.addController("TempEdge",{});
+    _tmpEdge.end_pos = _point;
+    _tmpEdge.from_controller = _from;
+    _tmpEdge.redraw();
+    this.click_target = _tmpEdge;
+}
+
 Rkns.Renderer.Scene.prototype.onMouseMove = function(_event) {
     var _hitResult = paper.project.hitTest(_event.point);
     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
@@ -700,11 +782,10 @@
     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
         this.click_target = _hitResult.item.__controller;
         if (this.click_target.type === "node" && _hitResult.type === "stroke") {
-            var _tmpEdge = this.addController("TempEdge",{});
-            _tmpEdge.end_pos = _event.point;
-            _tmpEdge.from_controller = this.click_target;
-            _tmpEdge.redraw();
-            this.click_target = _tmpEdge;
+            this.addTempEdge(this.click_target, _event.point);
+        }
+        if (this.click_target.type === "node-link-button") {
+            this.addTempEdge(this.click_target.node_controller, _event.point);
         }
     } else {
         this.click_target = null;