diff --git a/addons/web_diagram/static/src/js/diagram.js b/addons/web_diagram/static/src/js/diagram.js index 2c6bb29d8ff..84112262718 100644 --- a/addons/web_diagram/static/src/js/diagram.js +++ b/addons/web_diagram/static/src/js/diagram.js @@ -115,25 +115,34 @@ openerp.web.DiagramView = openerp.web.View.extend({ // Set-up the drawing elements of the diagram draw_diagram: function(result) { var self = this; - console.log(result); var res_nodes = result['nodes']; var res_edges = result['conn']; this.parent_field = result.parent_field; - var id_to_node = {} + var id_to_node = {}; - var style = { "edge" : "#A0A0A0", - "edge_label" : "#555", - "text" : "#333", - "outline" : "#333", - "selected" : "#0097BE", - "gray" : "#DCDCDC", - "white" : "#FFF", - "node_size_x" : 100, - "node_size_y" : 70, - "edge_spacing" : 100, - "edge_label_font_size" : 10 }; + var style = { "edge_color" : "#A0A0A0", + "edge_label_color" : "#555", + "edge_label_font_size" : 10, + "edge_width" : 2, + "edge_spacing" : 100, + "edge_loop_radius" : 100, + + "node_label_color" : "#333", + "node_label_font_size" : 12, + "node_outline_color" : "#333", + "node_outline_width" : 1, + "node_selected_color" : "#0097BE", + "node_selected_width" : 2, + "node_size_x" : 110, + "node_size_y" : 80, + "connector_active_color" : "#FFF", + "connector_radius" : 4, + + "gray" : "#DCDCDC", + "white" : "#FFF", + }; $('#dia-canvas').empty(); // remove previous diagram @@ -145,7 +154,7 @@ openerp.web.DiagramView = openerp.web.View.extend({ var n = new CuteNode( graph, node.x + 50, //FIXME the +50 should be in the layout algorithm node.y + 50, - CuteGraph.wordwrap(node.name, 16), + CuteGraph.wordwrap(node.name, 14), node.shape === 'rectangle' ? 'rect' : 'circle', node.color === 'white' ? style.white : style.gray ); n.id = node.id; @@ -238,7 +247,7 @@ openerp.web.DiagramView = openerp.web.View.extend({ _.each(form_fields, function(fld) { if (!(fld in form_controller.fields)) { return; } var field = form_controller.fields[fld]; - field.set_value([self.id,self.active_model]); + field.set_value(self.id); field.dirty = true; }); }); diff --git a/addons/web_diagram/static/src/js/graph.js b/addons/web_diagram/static/src/js/graph.js index 9f77b40303e..11afc2f2182 100644 --- a/addons/web_diagram/static/src/js/graph.js +++ b/addons/web_diagram/static/src/js/graph.js @@ -15,7 +15,9 @@ function Connector(graph,node,pos_x,pos_y){ var visible = false; var conn_circle = graph.r.circle(node.get_pos().x + pos_x, node.get_pos().y + pos_y,4); - conn_circle.attr({'opacity':0, 'fill':graph.style.outline,'stroke':'none'}); + conn_circle.attr({ 'opacity': 0, + 'fill': graph.style.node_outline_color, + 'stroke': 'none' }); conn_circle.transform(graph.get_transform()); graph.set_scrolling(conn_circle); @@ -23,21 +25,26 @@ this.update_pos = function(){ conn_circle.attr({'cx':node.get_pos().x + pos_x, 'cy':node.get_pos().y + pos_y}); - } + }; this.get_pos = function(){ return new node.get_pos().add_xy(pos_x,pos_y); - } + }; function hover_in(){ if(!visible){ return;} conn_circle.animate({'r':8},300,'elastic'); if(graph.creating_edge){ graph.target_node = node; - conn_circle.animate({'fill':graph.style.white,'stroke':graph.style.outline,'stroke-width':2},100,'linear'); + conn_circle.animate({ 'fill': graph.style.connector_active_color, + 'stroke': graph.style.node_outline_color, + 'stroke-width': graph.style.node_selected_width, + },100,'linear'); } } function hover_out(){ if(!visible){ return;} - conn_circle.animate({'r':4, 'fill':graph.style.outline, 'stroke':'none'},400,'linear'); + conn_circle.animate({ 'r':graph.style.connector_radius, + 'fill':graph.style.node_outline_color, + 'stroke':'none'},400,'linear'); graph.target_node = null; } conn_circle.hover(hover_in,hover_out); @@ -51,25 +58,25 @@ self.edge_end = new EdgeEnd(self.ox, self.oy); self.edge_tmp = new GraphEdge(graph,'',self.edge_start,self.edge_end,true); graph.creating_edge = true; - } + }; var drag_move = function(dx,dy){ if(!visible){ return; } self.edge_end.x = self.ox + dx; self.edge_end.y = self.oy + dy; self.edge_tmp.update(); - } + }; var drag_up = function(){ if(!visible){ return; } graph.creating_edge = false; self.edge_tmp.remove(); if(graph.target_node){ - edge_prop = GraphEdge.creation_callback(node,graph.target_node); + var edge_prop = GraphEdge.creation_callback(node,graph.target_node); if(edge_prop){ var new_edge = new GraphEdge(graph,edge_prop.label, node,graph.target_node); GraphEdge.new_edge_callback(new_edge); } } - } + }; conn_circle.drag(drag_move,drag_down,drag_up); function show(){ @@ -93,7 +100,7 @@ var nodes = []; // list of all nodes in the graph var edges = []; // list of all edges in the graph var graph = {}; // graph[n1.uid][n2.uid] -> list of all edges from n1 to n2 - var links = {} // links[n.uid] -> list of all edges from or to n + var links = {}; // links[n.uid] -> list of all edges from or to n var uid = 1; // all nodes and edges have an uid used to order their display when they are curved self.creating_edge = false; // true if we are dragging a new edge onto a node @@ -101,14 +108,13 @@ self.r = r; // the raphael instance self.style = style; // definition of the colors, spacing, fonts, ... used by the elements var tr_x = 0, tr_y = 0; // global translation coordinate - var scale = 1; // global scale var background = r.rect(0,0,'100%','100%').attr({'fill':'white', 'stroke':'none', 'opacity':0}); // return the global transform of the scene this.get_transform = function(){ return "T"+tr_x+","+tr_y - } + }; // translate every element of the graph except the background. @@ -117,34 +123,35 @@ var translate_all = function(dx,dy){ tr_x += dx; tr_y += dy; - tstr = self.get_transform(); + var tstr = self.get_transform(); r.forEach(function(el){ if(el != background){ el.transform(tstr); } }); - } + }; //Adds a mousewheel event callback to raph_element that scrolls the viewport this.set_scrolling = function(raph_element){ $(raph_element.node).bind('mousewheel',function(event,delta){ translate_all(0,delta*20); }); - } + }; + var px, py; // Graph translation when background is dragged var bg_drag_down = function(){ px = py = 0; - } + }; var bg_drag_move = function(x,y){ var dx = x - px; var dy = y - py; px = x; py = y; translate_all(dx,dy); - } - var bg_drag_up = function(){} + }; + var bg_drag_up = function(){}; background.drag( bg_drag_move, bg_drag_down, bg_drag_up); this.set_scrolling(background); @@ -154,10 +161,12 @@ nodes.push(n); n.uid = uid++; }; + //return the list of all nodes in the graph this.get_node_list = function(){ return nodes; }; + //adds an edge to the graph and sets its uid this.add_edge = function (n1,n2,e){ edges.push(e); @@ -173,6 +182,7 @@ links[n2.uid].push(e); } }; + //removes an edge from the graph this.remove_edge = function(edge){ edges = _.without(edges,edge); @@ -181,7 +191,7 @@ links[n1.uid] = _.without(links[n1.uid],edge); links[n2.uid] = _.without(links[n2.uid],edge); graph[n1.uid][n2.uid] = _.without(graph[n1.uid][n2.uid],edge); - } + }; //return the list of edges from n1 to n2 this.get_edge_list = function(n1,n2){ var list = []; @@ -193,7 +203,7 @@ this.get_linked_edge_list = function(n){ if(!links[n.uid]) return []; return links[n.uid]; - } + }; //return a curvature index so that all edges connecting n1,n2 have different curvatures this.get_edge_curvature = function(n1,n2,e){ var el_12 = this.get_edge_list(n1,n2); @@ -216,10 +226,10 @@ } } }; + // Returns the angle in degrees of the edge loop. We do not support more than 8 loops on one node this.get_loop_angle = function(n,e){ var loop_list = this.get_edge_list(n,n); - var lc = loop_list.length; var slots = []; // the 8 angles where we can put the loops for(var angle = 0; angle < 360; angle += 45){ @@ -265,7 +275,7 @@ index++; } } - index = index % slots.length; + index %= slots.length; return slots[index].angle_deg(); } @@ -280,7 +290,6 @@ var sx = graph.style.node_size_x; var node_fig = null; var selected = false; - this.update_time = 0; this.connectors = []; this.uid = 0; @@ -291,17 +300,21 @@ }else{ node_fig = r.rect(pos_x-sx/2,pos_y-sy/2,sx,sy); } - node_fig.attr({'fill':color, 'stroke':graph.style.outline,'stroke-width':1,'cursor':'pointer'}); + node_fig.attr({ 'fill': color, + 'stroke': graph.style.node_outline_color, + 'stroke-width': graph.style.node_outline_width, + 'cursor':'pointer' }); node_fig.transform(graph.get_transform()); graph.set_scrolling(node_fig); $(node_fig.node).addClass('foobar'); var node_label = r.text(pos_x,pos_y,label); - node_label.attr({'fill':graph.style.text,'cursor':'pointer'}); + node_label.attr({ 'fill': graph.style.node_label_color, + 'font-size': graph.style.node_label_font_size, + 'cursor': 'pointer' }); node_label.transform(graph.get_transform()); graph.set_scrolling(node_label); - $(node_label.node).css('text-shadow',"1px 2px 3px rgba(0,0,0,0.3)"); // redraws all edges linked to this node var update_linked_edges = function(){ @@ -309,7 +322,7 @@ for(var i = 0; i < edges.length; i++){ edges[i].update(); } - } + }; // sets the center position of the node var set_pos = function(pos){ @@ -323,11 +336,11 @@ self.connectors[i].update_pos(); } update_linked_edges(); - } + }; // returns the figure used to draw the node var get_fig = function(){ return node_fig; - } + }; // returns the center coordinates var get_pos = function(){ if(type == 'circle'){ @@ -335,26 +348,27 @@ }else{ return new Vec2(node_fig.attr('x') + sx/2, node_fig.attr('y') + sy/2); } - } + }; // return the label string var get_label = function(){ return node_label.attr("text"); - } + }; // sets the label string var set_label = function(text){ node_label.attr({'text':text}); - } + }; var get_bound = function(){ if(type == 'circle'){ return new BEllipse(get_pos().x,get_pos().y,sx/2,sy/2); }else{ return BRect.new_centered(get_pos().x,get_pos().y,sx,sy); } - } + }; // selects this node and deselects all other nodes var set_selected = function(){ if(!selected){ - node_fig.attr({'stroke':graph.style.selected, 'stroke-width':2}); + node_fig.attr({ 'stroke': graph.style.node_selected_color, + 'stroke-width': graph.style.node_selected_width }); selected = true; var nodes = graph.get_node_list(); for(var i = 0; i < nodes.length; i++){ @@ -366,17 +380,19 @@ self.connectors[i].show(); } } - } + }; // deselect this node var set_not_selected = function(){ if(selected){ - node_fig.animate({'stroke':graph.style.outline,'stroke-width':1},100,'linear'); + node_fig.animate({ 'stroke': graph.style.node_outline_color, + 'stroke-width': graph.style.node_outline_width }, + 100,'linear'); selected = false; } for(var i = 0; i < self.connectors.length; i++){ self.connectors[i].hide(); } - } + }; this.set_pos = set_pos; this.get_pos = get_pos; @@ -385,7 +401,7 @@ this.get_bound = get_bound; this.get_fig = get_fig; this.set_selected = set_selected; - this.set_not_selected = set_not_selected + this.set_not_selected = set_not_selected; this.update_linked_edges = update_linked_edges; @@ -401,14 +417,14 @@ node_fig.animate({'x':cx - sx/2, 'y':cy - sy/2, 'ẃidth':sx, 'height':sy},500,'elastic'); } set_selected(); - } + }; node_fig.click(click_action); node_label.click(click_action); //move the node when dragged var drag_down = function(){ this.opos = get_pos(); - } + }; var drag_move = function(dx,dy){ // we disable labels when moving for performance reasons, // updating the label position is quite expensive @@ -418,7 +434,7 @@ edges[i].label_disable(); } set_pos(this.opos.add_xy(dx,dy)); - } + }; var drag_up = function(){ //we re-enable the var edges = graph.get_linked_edge_list(self); @@ -426,7 +442,7 @@ edges[i].label_enable(); } - } + }; node_fig.drag(drag_move,drag_down,drag_up); node_label.drag(drag_move,drag_down,drag_up); @@ -456,7 +472,7 @@ GraphNode.double_click_callback = function(node){ console.log("double click from node:",node); - } + }; // creates a new edge with label 'label' from start to end. start and end must implement get_pos_*, // if tmp is true, the edge is not added to the graph, used for drag edges. @@ -464,7 +480,6 @@ function GraphEdge(graph,label,start,end,tmp){ var self = this; var r = graph.r; - var update_time = -1; var curvature = 0; // 0 = straight, != 0 curved var s,e; // positions of the start and end point of the line between start and end var mc; // position of the middle of the curve (bezier control point) @@ -547,7 +562,7 @@ var r = Vec2.new_polar_deg(rad,graph.get_loop_angle(start,self)); mc = s.add(r); - p = r.rotate_deg(90); + var p = r.rotate_deg(90); mc1 = mc.add(p.set_len(rad*0.5)); mc2 = mc.add(p.set_len(-rad*0.5)); @@ -566,16 +581,21 @@ } update_curve(); - var edge = r.path(edge_path).attr({'stroke':graph.style.edge, 'stroke-width':2, 'arrow-end':'block-wide-long', 'cursor':'pointer'}).insertBefore(graph.get_node_list()[0].get_fig()); + var edge = r.path(edge_path).attr({ 'stroke': graph.style.edge_color, + 'stroke-width': graph.style.edge_width, + 'arrow-end': 'block-wide-long', + 'cursor':'pointer' }).insertBefore(graph.get_node_list()[0].get_fig()); var labelpos = get_label_pos(edge); - var edge_label = r.text(labelpos.x, labelpos.y - elfs, label).attr({'fill':graph.style.edge_label, 'cursor':'pointer', 'font-size':elfs}); + var edge_label = r.text(labelpos.x, labelpos.y - elfs, label).attr({ + 'fill': graph.style.edge_label_color, + 'cursor': 'pointer', + 'font-size': elfs }); edge.transform(graph.get_transform()); graph.set_scrolling(edge); edge_label.transform(graph.get_transform()); graph.set_scrolling(edge_label); - $(edge_label.node).css('text-shadow',"1px 2px 3px rgba(0,0,0,0.3)"); //since we create an edge we need to recompute the edges that have the same start and end positions as this one @@ -647,7 +667,7 @@ GraphEdge.double_click_callback = function(edge){ console.log("double click from edge:",edge); - } + }; // this is the default edge creation callback. It is called before an edge is created // It returns an object containing the properties of the edge. @@ -670,7 +690,7 @@ var brk = '\n'; if (!str) { return str; } var regex = '.{1,' +width+ '}(\\s|$)' + (cut ? '|.{' +width+ '}|.+$' : '|\\S+?(\\s|$)'); - return str.match( RegExp(regex, 'g') ).join( brk ); + return str.match(new RegExp(regex, 'g') ).join( brk ); } window.CuteGraph = Graph; @@ -682,30 +702,3 @@ })(window); -/* -window.onload = function(){ - //Example - var style = { "background" :'url("grid.png")', - "edge" :"#A0A0A0", - "edge_label" :"#555", - "text" :"#333", - "outline" :"#000", - "selected" :"#0097BE", - "gray" :"#DCDCDC", - "white" :"#FFF", - "node_size_x" : 110, - "node_size_y" : 80, - "edge_spacing" : 100, - "edge_label_font_size" : 10 - "edge_loop_radius": 50 }; - - var r = new Raphael(document.getElementById("canvas_container"),'100%','100%'); - - var g = new CuteGraph(r,style); - - var n1 = new CuteNode(g,100,250,'Hello World','circle',colors.white); - var n2 = new CuteNode(g,400,250,'Hello Planet','rect',colors.white); - var n3 = new CuteNode(g,250,400,'Lonely Node','rect',colors.gray); - var e1 = new CuteEdge(g,'test',n1,n2); -}*/ - diff --git a/addons/web_diagram/static/src/js/vec2.js b/addons/web_diagram/static/src/js/vec2.js index 73b13d04125..c86246c2a7b 100644 --- a/addons/web_diagram/static/src/js/vec2.js +++ b/addons/web_diagram/static/src/js/vec2.js @@ -216,7 +216,7 @@ this.hx = rx; // half of the ellipse width on the x axis this.hy = ry; // half of the ellipse width on the y axis this.cx = cx; // x coordinate of the ellipse center - this.cy = cy; // y coordinqte of the ellipse center + this.cy = cy; // y coordinate of the ellipse center this.mx = cx + rx; // maximum x coordinate contained in the ellipse this.my = cy + ry; // maximum x coordinate contained in the ellipse } @@ -226,7 +226,7 @@ // boundary and a line segment defined by the start and end vectors a,b BEllipse.prototype.collide_segment = function(a,b){ // http://paulbourke.net/geometry/sphereline/ - collisions = [] + var collisions = []; if(a.equals(b)){ //we do not compute the intersection in this case. TODO ? return collisions; @@ -318,7 +318,7 @@ // boundary and a line segment defined by the start and end vectors a,b BRect.prototype.collide_segment = function(a,b){ - var collisions = [] + var collisions = []; var corners = [ new Vec2(this.x,this.y), new Vec2(this.x,this.my), new Vec2(this.mx,this.my), new Vec2(this.mx,this.y) ]; var pos = line_intersect(a,b,corners[0],corners[1]);