client/js/paper-renderer.js
changeset 36 d249d36ecc37
parent 35 10e0c23c849e
child 37 db991a757015
equal deleted inserted replaced
35:10e0c23c849e 36:d249d36ecc37
    15     _ARROW_WIDTH: 8,
    15     _ARROW_WIDTH: 8,
    16     _EDITOR_ARROW_LENGTH : 20,
    16     _EDITOR_ARROW_LENGTH : 20,
    17     _EDITOR_ARROW_WIDTH : 40,
    17     _EDITOR_ARROW_WIDTH : 40,
    18     _EDITOR_MARGIN : 15,
    18     _EDITOR_MARGIN : 15,
    19     _EDITOR_PADDING : 10,
    19     _EDITOR_PADDING : 10,
    20     _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0'])
    20     _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0']),
       
    21     _CLICKMODE_ADDNODE : 1,
       
    22     _CLICKMODE_STARTEDGE : 2,
       
    23     _CLICKMODE_ENDEDGE : 3
    21 }
    24 }
    22 
    25 
    23 Rkns.Renderer.Utils = {
    26 Rkns.Renderer.Utils = {
    24     drawEditBox : function(_coords, _path, _width, _xmargin, _selector) {
    27     drawEditBox : function(_coords, _path, _width, _xmargin, _selector) {
    25         _selector.css({
    28         _selector.css({
   270 
   273 
   271 Rkns.Renderer.Node.prototype.mouseup = function(_event) {
   274 Rkns.Renderer.Node.prototype.mouseup = function(_event) {
   272     if (!this.renderer.is_dragging) {
   275     if (!this.renderer.is_dragging) {
   273         this.openEditor();
   276         this.openEditor();
   274     }
   277     }
       
   278     this.renderer.click_target = null;
       
   279     this.renderer.is_dragging = false;
   275 }
   280 }
   276 
   281 
   277 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   282 Rkns.Renderer.Node.prototype.destroy = function(_event) {
   278     this.edit_button.destroy();
   283     this.edit_button.destroy();
   279     this.remove_button.destroy();
   284     this.remove_button.destroy();
   374 
   379 
   375 Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
   380 Rkns.Renderer.Edge.prototype.mouseup = function(_event) {
   376     if (!this.renderer.is_dragging) {
   381     if (!this.renderer.is_dragging) {
   377         this.openEditor();
   382         this.openEditor();
   378     }
   383     }
       
   384     this.renderer.click_target = null;
       
   385     this.renderer.is_dragging = false;
   379 }
   386 }
   380 
   387 
   381 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   388 Rkns.Renderer.Edge.prototype.paperShift = function(_delta) {
   382     this.from_representation.paperShift(_delta);
   389     this.from_representation.paperShift(_delta);
   383     this.to_representation.paperShift(_delta);
   390     this.to_representation.paperShift(_delta);
   434     this.renderer.findTarget(_hitResult);
   441     this.renderer.findTarget(_hitResult);
   435     this.redraw();
   442     this.redraw();
   436 }
   443 }
   437 
   444 
   438 Rkns.Renderer.TempEdge.prototype.mouseup = function(_event) {
   445 Rkns.Renderer.TempEdge.prototype.mouseup = function(_event) {
   439     var _hitResult = paper.project.hitTest(_event.point);
   446     var _hitResult = paper.project.hitTest(_event.point),
       
   447         _model = this.from_representation.model,
       
   448         _endDrag = true;
   440     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
   449     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
   441         var _target = _hitResult.item.__representation;
   450         var _target = _hitResult.item.__representation;
   442         if (_target.type === "Node" && this.from_representation.model !== _target.model) {
   451         if (_target.type === "Node" && _model !== _target.model) {
   443             var _data = {
   452             var _data = {
   444                 id: Rkns.Utils.getUID('edge'),
   453                 id: Rkns.Utils.getUID('edge'),
   445                 created_by: this.renderer.renkan.current_user,
   454                 created_by: this.renderer.renkan.current_user,
   446                 from: this.from_representation.model.get("_id"),
   455                 from: _model.get("_id"),
   447                 to: _target.model.get("_id")
   456                 to: _target.model.get("_id")
   448             };
   457             };
   449             this.project.addEdge(_data);
   458             this.project.addEdge(_data);
   450         }
   459         }
   451     }
   460         if (_model === _target.model || (_target.node_representation && _target.node_representation.model === _model)) {
   452     this.renderer.removeRepresentation(this);
   461             _endDrag = false;
       
   462             this.renderer.is_dragging = true;
       
   463         }
       
   464     }
       
   465     if (_endDrag) {
       
   466         this.renderer.click_target = null;
       
   467         this.renderer.is_dragging = false;
       
   468         this.renderer.removeRepresentation(this);
       
   469         paper.view.draw();
       
   470     }
   453 }
   471 }
   454 
   472 
   455 Rkns.Renderer.TempEdge.prototype.destroy = function() {
   473 Rkns.Renderer.TempEdge.prototype.destroy = function() {
   456     this.arrow.remove();
   474     this.arrow.remove();
   457     this.line.remove();
   475     this.line.remove();
   677         this.node_representation.unselect();
   695         this.node_representation.unselect();
   678     }
   696     }
   679 }
   697 }
   680 
   698 
   681 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
   699 Rkns.Renderer.NodeRemoveButton.prototype.mouseup = function() {
       
   700     this.renderer.removeRepresentationsOfType("editor");
   682     if (confirm('Do you really wish to remove node "' + this.node_representation.model.get("title") + '"?')) {
   701     if (confirm('Do you really wish to remove node "' + this.node_representation.model.get("title") + '"?')) {
   683         this.project.removeNode(this.node_representation.model);
   702         this.project.removeNode(this.node_representation.model);
   684     }
   703     }
   685 }
   704 }
   686 
   705 
   799         this.edge_representation.unselect();
   818         this.edge_representation.unselect();
   800     }
   819     }
   801 }
   820 }
   802 
   821 
   803 Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
   822 Rkns.Renderer.EdgeRemoveButton.prototype.mouseup = function() {
       
   823     this.renderer.removeRepresentationsOfType("editor");
   804     if (confirm('Do you really wish to remove edge "' + this.edge_representation.model.get("title") + '"?')) {
   824     if (confirm('Do you really wish to remove edge "' + this.edge_representation.model.get("title") + '"?')) {
   805         this.project.removeEdge(this.edge_representation.model);
   825         this.project.removeEdge(this.edge_representation.model);
   806     }
   826     }
   807 }
   827 }
   808 
   828 
   819     this.$.html(this.template({
   839     this.$.html(this.template({
   820         l10n: _renkan.l10n
   840         l10n: _renkan.l10n
   821     }))
   841     }))
   822     this.canvas_$ = this.$.find(".Rk-Canvas");
   842     this.canvas_$ = this.$.find(".Rk-Canvas");
   823     this.editor_$ = this.$.find(".Rk-Editor");
   843     this.editor_$ = this.$.find(".Rk-Editor");
       
   844     this.notif_$ = this.$.find(".Rk-Notifications");
   824     paper.setup(this.canvas_$[0]);
   845     paper.setup(this.canvas_$[0]);
   825     this.scale = 1;
   846     this.scale = 1;
   826     this.offset = paper.view.center;
   847     this.offset = paper.view.center;
   827     this.totalScroll = 0;
   848     this.totalScroll = 0;
   828     this.click_target = null;
   849     this.click_target = null;
   829     this.selected_target = null;
   850     this.selected_target = null;
   830     this.edge_layer = new paper.Layer();
   851     this.edge_layer = new paper.Layer();
   831     this.node_layer = new paper.Layer();
   852     this.node_layer = new paper.Layer();
   832     this.overlay_layer = new paper.Layer();
   853     this.overlay_layer = new paper.Layer();
   833     this.bundles = [];
   854     this.bundles = [];
       
   855     this.click_mode = false;
   834     var _tool = new paper.Tool(),
   856     var _tool = new paper.Tool(),
   835         _this = this;
   857         _this = this;
   836     _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
   858     _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
   837     _tool.onMouseMove = function(_event) {
   859     _tool.onMouseMove = function(_event) {
   838         _this.onMouseMove(_event);
   860         _this.onMouseMove(_event);
   869             _this.canvas_$.height()
   891             _this.canvas_$.height()
   870         ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
   892         ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
   871         _this.setScale( _this.scale * Math.SQRT2 );
   893         _this.setScale( _this.scale * Math.SQRT2 );
   872         _this.redraw();
   894         _this.redraw();
   873     });
   895     });
   874     this.$.find(".Rk-Users").mouseenter(function() {
   896     this.$.find(".Rk-CurrentUser").mouseenter(
   875         _this.$.find(".Rk-UserList").slideDown();
   897         function() { _this.$.find(".Rk-UserList").slideDown() }
   876     }).mouseleave(function() {
   898     );
   877         _this.$.find(".Rk-UserList").slideUp();
   899     this.$.find(".Rk-Users").mouseleave(
   878     });
   900         function() { _this.$.find(".Rk-UserList").slideUp(); }
       
   901     );
   879     this.$.find(".Rk-FullScreen-Button").click(function() {
   902     this.$.find(".Rk-FullScreen-Button").click(function() {
   880         var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen,
   903         var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen,
   881             _el = _this.renkan.$[0],
   904             _el = _this.renkan.$[0],
   882             _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"],
   905             _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"],
   883             _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"];
   906             _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"];
   896                 }
   919                 }
   897             }
   920             }
   898         }
   921         }
   899     });
   922     });
   900     this.$.find(".Rk-AddNode-Button").click(function() {
   923     this.$.find(".Rk-AddNode-Button").click(function() {
   901         var _coords = _this.toModelCoords(paper.view.center),
   924         if (_this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
   902             _data = {
   925             _this.click_mode = false;
   903                 id: Rkns.Utils.getUID('node'),
   926             _this.notif_$.hide();
   904                 created_by: _this.renkan.current_user,
   927         } else {
   905                 position: {
   928             _this.click_mode = Rkns.Renderer._CLICKMODE_ADDNODE;
   906                     x: _coords.x,
   929             _this.notif_$.html(_renkan.l10n.notif_add_node).fadeIn();
   907                     y: _coords.y
   930         }
   908                 }
   931     });
   909             };
   932     this.$.find(".Rk-AddEdge-Button").click(function() {
   910             _node = _this.renkan.project.addNode(_data);
   933         if (_this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE || _this.click_mode === Rkns.Renderer._CLICKMODE_ENDEDGE) {
   911         _this.getRepresentationByModel(_node).openEditor();
   934             _this.click_mode = false;
       
   935             _this.notif_$.hide();
       
   936         } else {
       
   937             _this.click_mode = Rkns.Renderer._CLICKMODE_STARTEDGE;
       
   938             _this.notif_$.html(_renkan.l10n.notif_start_edge).fadeIn();
       
   939         }
   912     });
   940     });
   913     this.$.find(".Rk-TopBar-Button").mouseover(function() {
   941     this.$.find(".Rk-TopBar-Button").mouseover(function() {
   914         Rkns.$(this).find(".Rk-TopBar-Tooltip").show();
   942         Rkns.$(this).find(".Rk-TopBar-Tooltip").show();
   915     }).mouseout(function() {
   943     }).mouseout(function() {
   916         Rkns.$(this).find(".Rk-TopBar-Tooltip").hide();
   944         Rkns.$(this).find(".Rk-TopBar-Tooltip").hide();
   945     
   973     
   946     this.redraw();
   974     this.redraw();
   947 }
   975 }
   948 
   976 
   949 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
   977 Rkns.Renderer.Scene.prototype.template = Rkns._.template(
   950     '<div class="Rk-TopBar"><h3 class="Rk-PadTitle">Untitled Project</h3>'
   978     '<div class="Rk-TopBar"><h3 class="Rk-PadTitle"><%=l10n.untitled_project%></h3>'
   951     + '<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>'
   979     + '<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>'
   952     + '<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>'
   980     + '<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>'
   953     + '<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>'
   981     + '<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>'
       
   982     + '<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>'
   954     + '<div class="Rk-TopBar-Separator"></div></div>'
   983     + '<div class="Rk-TopBar-Separator"></div></div>'
   955     + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor">'
   984     + '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor"><div class="Rk-Notifications"></div>'
   956     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
   985     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
   957     + '</div>'
   986     + '</div>'
   958 );
   987 );
   959 
   988 
   960 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
   989 Rkns.Renderer.Scene.prototype.addToBundles = function(_edgeRepr) {
  1136         this.findTarget(_hitResult);
  1165         this.findTarget(_hitResult);
  1137     }
  1166     }
  1138 }
  1167 }
  1139 
  1168 
  1140 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
  1169 Rkns.Renderer.Scene.prototype.onMouseDown = function(_event) {
  1141     this.is_dragging = false;
  1170     if (!this.click_target || this.click_target.type !== "temp-edge") {
  1142     var _hitResult = paper.project.hitTest(_event.point);
  1171         this.is_dragging = false;
  1143     if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
  1172         var _hitResult = paper.project.hitTest(_event.point);
  1144         this.click_target = _hitResult.item.__representation;
  1173         if (_hitResult && typeof _hitResult.item.__representation !== "undefined") {
  1145         if (this.click_target.type === "Node" && _hitResult.type === "stroke") {
  1174             this.click_target = _hitResult.item.__representation;
       
  1175             if (this.click_target.type === "Node-link-button") {
       
  1176                 this.removeRepresentationsOfType("editor");
       
  1177                 this.addTempEdge(this.click_target.node_representation, _event.point);
       
  1178             }
       
  1179         } else {
       
  1180             this.click_target = null;
       
  1181             if (this.click_mode === Rkns.Renderer._CLICKMODE_ADDNODE) {
       
  1182                 var _coords = this.toModelCoords(_event.point),
       
  1183                     _data = {
       
  1184                         id: Rkns.Utils.getUID('node'),
       
  1185                         created_by: this.renkan.current_user,
       
  1186                         position: {
       
  1187                             x: _coords.x,
       
  1188                             y: _coords.y
       
  1189                         }
       
  1190                     };
       
  1191                     _node = this.renkan.project.addNode(_data);
       
  1192                 this.getRepresentationByModel(_node).openEditor();
       
  1193             }
       
  1194         }
       
  1195     }
       
  1196     if (this.click_mode) {
       
  1197         if (this.click_mode === Rkns.Renderer._CLICKMODE_STARTEDGE && this.click_target && this.click_target.type === "Node") {
       
  1198             this.removeRepresentationsOfType("editor");
  1146             this.addTempEdge(this.click_target, _event.point);
  1199             this.addTempEdge(this.click_target, _event.point);
  1147         }
  1200             this.click_mode = Rkns.Renderer._CLICKMODE_ENDEDGE;
  1148         if (this.click_target.type === "Node-link-button") {
  1201             this.notif_$.fadeOut(function() {
  1149             this.addTempEdge(this.click_target.node_representation, _event.point);
  1202                 Rkns.$(this).html(_renkan.l10n.notif_end_edge).fadeIn();
  1150         }
  1203             });
  1151     } else {
  1204         } else {
  1152         this.click_target = null;
  1205             this.notif_$.hide();
       
  1206             this.click_mode = false;
       
  1207         }
  1153     }
  1208     }
  1154 }
  1209 }
  1155 
  1210 
  1156 Rkns.Renderer.Scene.prototype.onMouseDrag = function(_event) {
  1211 Rkns.Renderer.Scene.prototype.onMouseDrag = function(_event) {
  1157     this.is_dragging = true;
  1212     this.is_dragging = true;
  1167                     _event.pageX - _off.left,
  1222                     _event.pageX - _off.left,
  1168                     _event.pageY - _off.top
  1223                     _event.pageY - _off.top
  1169                 ])
  1224                 ])
  1170             }
  1225             }
  1171         );
  1226         );
  1172     }
  1227     } else {
  1173     this.is_dragging = false;
  1228         this.click_target = null;
  1174     this.click_target = null;
  1229         this.is_dragging = false;
       
  1230     }
  1175 }
  1231 }
  1176 
  1232 
  1177 Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) {
  1233 Rkns.Renderer.Scene.prototype.onScroll = function(_event, _scrolldelta) {
  1178     this.totalScroll += _scrolldelta;
  1234     this.totalScroll += _scrolldelta;
  1179     if (Math.abs(this.totalScroll) >= 1) {
  1235     if (Math.abs(this.totalScroll) >= 1) {