Subversion Repositories wimsdev

Rev

Rev 15690 | Rev 16718 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "canvasdraw.h"
  2.  
  3. void add_drag_code(int canvas_cnt,int use_dragstuff, int dragstuff[],int reply_format){
  4. /* in drag& drop / onclick library:
  5.  use_dragstuff == 1 : no mouse code
  6.     obj_type = 1 == rect / rects
  7.     obj_type = 2 == point / points (do not scale with zoom)
  8.     obj_type = 3 == ellipse
  9.     obj_type = 4 == polyline / segment / segments /line / vline / hline
  10.     obj_type = 5 == closed path (polygon)
  11.     obj_type = 6 == roundrect /roundrects
  12.     obj_type = 7 == crosshair / crosshairs
  13.     obj_type = 8 == arrow / arrows
  14.     obj_type = 9 == curve
  15.     obj_type = 10== arrow2 / arrows2
  16.     obj_type = 11== parallel  (no drag or onclick)
  17.     obj_type = 12== arc : radius is in pixels , so no zooming in/out
  18.     obj_type = 13== circle / circles (will scale on zoom)
  19.     obj_type = 14== text (will not scale or pan on zoom)
  20.     obj_type = 15== animated point on curve
  21.     obj_type = 16== pixels
  22.     obj_type = 17== new arc [command angle] :radius in x-range, so will scale on zooming in/out
  23.     obj_type = 18== halfline
  24.     obj_type = 19== yerrorbars
  25.     obj_type = 20== xerrorbars
  26.     obj_type = 21== curvedarrow
  27.     obj_type = 22== use a slider (...)
  28.     obj_type = 23== image
  29.     obj_type = 24== arrowarc right
  30.     obj_type = 25== arrowarc left
  31.     obj_type = 26== arrowarc left/right
  32. arc
  33. x[0] = x[1] = xc = double_data[0]
  34. y[0] = y[1] = yc = double_data[1]
  35. w[0] = width = int_data[0]
  36. w[1] = height = int_data[1]
  37. h[0] = start_angle = double_data[2]
  38. h[1] = end_angle = double_data[3]
  39.  
  40. use_offset only for text shape objects...
  41.  0=none;
  42.  1=yoffset
  43.  2=xoffset
  44.  3=xyoffset
  45.  4=centered
  46.  
  47. int onclick = 0;  0 = noninteractive ; 1 = onclick ; 2 = draggable
  48. type= object type
  49.  
  50. verwijderd: direction : dragging in xy=0 , in x=1 in y=2 vervangen dooor use_snap  en multisnap_check(x,y,use_snap)
  51. use_snap:   0 = none 1=grid : 2=x-grid : 3=y-grid : 4=snap to points  
  52. obj.angle == RADIANS!
  53. use_filled 0=no fill, 1=fill,2=grid,3=hatch,4=diamond,5=dot,6=image
  54.  
  55. rotate+translate+linear: is done in C-functions...e.g. original coordinates are transformed
  56. NO NEED for javascript rotations in dragstuff...except for ANGLE
  57. */
  58. int i;
  59. fprintf(js_include_file,"\n/* complete drag_drop_onclick shape library */\
  60. if( typeof(dragdrop_precision) == 'undefined' ){var dragdrop_precision = 100;};\
  61. function Shape(drag_type,object_cnt,onclick,use_snap,type,x,y,w,h,line_width,stroke_color,stroke_opacity,fill_color,fill_opacity,use_filled,use_dashed,dashtype0,dashtype1,use_rotate,angle,text,font_size,font_family,use_slider,rotation_center,use_offset){\
  62. this.drag_type = drag_type || 0;\
  63. this.stroke_opacity = stroke_opacity || 1.0;\
  64. this.stroke_color = \"rgba(\"+stroke_color+\",\"+stroke_opacity+\")\" || '#FF0000';\
  65. this.fill_opacity = fill_opacity || 1.0;\
  66. this.fill_color = \"rgba(\"+fill_color+\",\"+fill_opacity+\")\" || '#FF0000';\
  67. this.use_filled = use_filled || 0;\
  68. if( this.use_filled > 1 ){ this.fill_pattern = create_Pattern(0,0,this.use_filled,this.fill_color);};\
  69. this.use_slider = use_slider;\
  70. this.text = text || 0;\
  71. this.font_size = font_size || 12;\
  72. if( this.font_size == 12 ){ this.font_size = parseInt(font_family); };\
  73. this.font_family = font_family || this.font_size+'px Ariel';\
  74. this.org_font_family = this.font_family;\
  75. this.textwidth = 0;\
  76. this.textheight = 0;\
  77. if(type == 14 ){ this.use_rotate = use_rotate;this.angle=angle*Math.PI/180;}else{this.angle=0;this.use_rotate=0;};\
  78. this.object_cnt = object_cnt;\
  79. this.onclick = onclick;\
  80. this.use_snap = use_snap || 0;\
  81. this.type = type || 1;\
  82. if( this.use_slider[0] != -1 ){ slidergroup[this.object_cnt] = null;};\
  83. this.xorg = x;this.yorg = y;\
  84. this.use_once = true;\
  85. this.x = [x.length];this.y = [x.length];this.w = [x.length];this.h = [x.length];\
  86. for(var p=0;p<x.length;p++){this.x[p] = x2px(x[p]-xstart);this.y[p] = y2px(y[p]-ystart);if( p > w.length){this.w[p] = w[0];this.h[p] = h[0];}else{this.w[p] = w[p];this.h[p] = h[p];};};\
  87. if( rotation_center != null ){this.use_rotation_center = 1;this.rotation_center = [x2px(rotation_center[0]),y2px(rotation_center[1])];}else{this.use_rotation_center = 0;this.rotation_center = [this.x[0],this.y[0]];};\
  88. this.line_width = line_width || 2;\
  89. this.org_line_width = line_width || 2;\
  90. this.use_filled = use_filled || 0;\
  91. this.use_dashed = use_dashed || 0;\
  92. this.dashtype0 = dashtype0 || 4;\
  93. this.dashtype1 = dashtype1 || 4;\
  94. this.use_offset = use_offset || 0;\
  95. if( this.onclick == 2 && this.use_slider != -1){this.onclick = 5;};\
  96. dragdrop_reply[object_cnt] = {object_cnt:this.object_cnt,type:onclick,x:this.x[0],y:this.y[0],r:this.w[0],angle:this.angle,clicked:0};\
  97. };");
  98.  
  99. // dragdrop_reply[object_cnt] = {object_cnt:this.object_cnt,type:onclick,x:this.x[0],y:this.y[0],r:this.w[0],angle:this.angle,clicked:0};
  100.  
  101. if( dragstuff[21] == 1 ){
  102. fprintf(js_include_file,"\n/* add curvedarrow... is this really the place for it??? */\
  103. function drawCurvedArrow(ctx,x1,y1,x3,y3,x2,y2,arrowhead,type){ctx.save();var angle1 = Math.atan2(x3 - x2,y3 - y2) + Math.PI;ctx.beginPath();if(type == 2){var angle2 =Math.atan2(x3 - x1,y3 - y1) + Math.PI;ctx.moveTo(x1,y1);ctx.moveTo(x1 - (arrowhead * Math.sin(angle2 - Math.PI / 6)),y1 - (arrowhead * Math.cos(angle2 - Math.PI / 6)));ctx.lineTo(x1, y1);ctx.lineTo(x1 - (arrowhead * Math.sin(angle2 + Math.PI / 6)),y1 - (arrowhead * Math.cos(angle2 + Math.PI / 6)));};ctx.moveTo(x1,y1);ctx.quadraticCurveTo(x3,y3,x2,y2);ctx.moveTo(x2 - (arrowhead * Math.sin(angle1 - Math.PI / 6)),y2 - (arrowhead * Math.cos(angle1 - Math.PI / 6)));ctx.lineTo(x2, y2);ctx.lineTo(x2 - (arrowhead * Math.sin(angle1 + Math.PI / 6)),y2 - (arrowhead * Math.cos(angle1 + Math.PI / 6)));ctx.stroke();ctx.closePath();ctx.restore();};");
  104. }
  105.  
  106. fprintf(js_include_file,"\n/* add basic drawstuff,but don't go here if nothing has changed... */\
  107. Shape.prototype.draw = function(ctx){\
  108. if(dragstuff.valid === true){return;};\
  109. ctx.lineWidth = this.line_width;ctx.strokeStyle = this.stroke_color;\
  110. if( this.use_filled > 1 ){ ctx.fillStyle = this.fill_pattern; }else{ ctx.fillStyle = this.fill_color; };\
  111. ctx.lineJoin = \"round\";ctx.save();\
  112. if(this.use_rotate == 1){if(this.use_rotation_center == 0 ){ this.rotation_center[0] = this.x[0];this.rotation_center[1] = this.y[0];};ctx.translate(this.rotation_center[0],this.rotation_center[1]);ctx.rotate(this.angle);ctx.translate(-1*(this.rotation_center[0]),-1*(this.rotation_center[1]));};\
  113. ctx.beginPath();\
  114. switch(this.type){default:break;");
  115.  
  116. for( i=0; i < MAX_DRAGSTUFF; i++){
  117.   if( dragstuff[i] == 1 ){
  118.    switch(i){
  119.     case 1: fprintf(js_include_file,"case 1: for(var p = 0 ; p < this.x.length;p = p+4){ctx.rect(this.x[p], this.y[p], this.x[p+1]-this.x[p], this.y[p+2] - this.y[p]);};break;");break;
  120.     case 2: fprintf(js_include_file,"case 2: ctx.arc(this.x[0],this.y[0],0.5*this.w[0],0,2*Math.PI,false);break;");break;
  121.     case 3: fprintf(js_include_file,"case 3: ctx.save();var w = 0.5*(scale_x_radius(this.w[0]));var h = 0.5*(scale_y_radius(this.h[0]));ctx.scale(1,h/w);ctx.beginPath();ctx.arc(this.x[0], w/h*this.y[0], w, 0, 2 * Math.PI);if(this.use_filled == 1){ ctx.fillStyle = this.fill_color; ctx.fill(); };ctx.closePath();ctx.stroke();ctx.restore();break;");break;
  122.     case 4: fprintf(js_include_file,"case 4: for(var p = 0; p < this.x.length - 1;p++){ctx.moveTo(this.x[p], this.y[p]);ctx.lineTo(this.x[p+1],this.y[p+1]);};break;");break;
  123.     case 5: fprintf(js_include_file,"case 5: ctx.moveTo(this.x[0],this.y[0]);for(var p = 1; p < this.x.length;p++){ctx.lineTo(this.x[p],this.y[p]);};ctx.lineTo(this.x[0],this.y[0]);break;");break;
  124.     case 6: fprintf(js_include_file,"case 6: var w = this.x[1] - this.x[0];var h = this.y[1] - this.y[0];var r = this.w[0];ctx.beginPath();ctx.moveTo(this.x[0] + r, this.y[0]);ctx.lineTo(this.x[0] + w - r, this.y[0]);ctx.quadraticCurveTo(this.x[0] + w, this.y[0], this.x[0] + w, this.y[0] + r);ctx.lineTo(this.x[0] + w, this.y[0] + h - r);ctx.quadraticCurveTo(this.x[0] + w, this.y[0] + h, this.x[0] + w - r, this.y[0] + h);ctx.lineTo(this.x[0] + r, this.y[0] + h);ctx.quadraticCurveTo(this.x[0], this.y[0] + h, this.x[0], this.y[0] + h - r);ctx.lineTo(this.x[0], this.y[0] + r);ctx.quadraticCurveTo(this.x[0], this.y[0], this.x[0] + r, this.y[0]);ctx.closePath();break;");break;
  125.     case 7: fprintf(js_include_file,"case 7: ctx.moveTo(this.x[0]-this.w[0],this.y[0]-this.h[0]);ctx.lineTo(this.x[0]+this.w[0],this.y[0]+this.h[0]);ctx.moveTo(this.x[0]-this.w[0],this.y[0]+this.h[0]);ctx.lineTo(this.x[0]+this.w[0],this.y[0]-this.h[0]);break;");break;
  126.     case 8: fprintf(js_include_file,"case 8: var x1,x2,y1,y2,dx,dy,h;var len = this.x.length;var arrow_head = this.w[0];for(var p = 0 ; p < len ; p = p+2 ){x1 = this.x[p];y1 = this.y[p];x2 = this.x[p+1];y2 = this.y[p+1];dx = x2 - x1;dy = y2 - y1;h = Math.sqrt(dx*dx+dy*dy);ctx.save();ctx.setLineDash([]);ctx.translate(x2,y2);ctx.rotate(Math.atan2(dy,dx));ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(-1*arrow_head,-0.5*arrow_head);ctx.lineTo(-1*arrow_head, 0.5*arrow_head);ctx.closePath();ctx.stroke();ctx.fill();ctx.restore();ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.closePath();};break;");
  127.     case 9: fprintf(js_include_file,"case 9: ctx.moveTo(this.x[0], this.y[0]);for(var p = 1; p < this.x.length - 1;p++){if( Math.abs(this.y[p] - this.y[p-1]) < ysize && Math.abs(this.y[p+1] - this.y[p]) < ysize ){ctx.lineTo(this.x[p],this.y[p]);}else{ctx.moveTo(this.x[p],this.y[p]);};};break;");break;
  128.     case 10: fprintf(js_include_file,"case 10: var dx;var dy;var len;ctx.save();if(this.use_dashed == 1 ){if( ctx.setLineDash ){ ctx.setLineDash([this.dashtype0,this.dashtype1]);}else{ ctx.mozDash = [this.dashtype0,this.dashtype1];};};dx = this.x[1] - this.x[0];dy = this.y[1] - this.y[0];len = Math.sqrt(dx*dx+dy*dy);ctx.translate(this.x[1],this.y[1]);ctx.rotate(Math.atan2(dy,dx));ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(-len,0);ctx.closePath();ctx.stroke();ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(-1*this.w[0],0.5*this.w[0]);ctx.lineTo(-1*this.w[0],-0.5*this.w[0]);ctx.closePath();ctx.lineCap = \"round\";ctx.fill();ctx.restore();ctx.save();ctx.translate(this.x[0],this.y[0]);ctx.rotate(Math.atan2(dy,dx));ctx.beginPath();ctx.moveTo(0,0);ctx.lineTo(this.w[0],0.4*this.w[0]);ctx.lineTo(this.w[0],-0.4*this.w[0]);ctx.closePath();ctx.lineCap = \"round\";ctx.fill(); break;");break;
  129.     case 11: fprintf(js_include_file,"case 11: var x1 = this.x[0];var y1 = this.y[0];var x2 = this.x[1];var y2 = this.y[1];var dx = this.x[2];var dy = this.y[2];var n  = this.w[0];for(var p = 0 ; p < n ; p++ ){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.stroke();x1 = x1 + dx;y1 = y1 + dy;x2 = x2 + dx;y2 = y2 + dy;ctx.closePath();};break;");break;
  130.     case 12: fprintf(js_include_file,"case 12: ctx.save();var start;var end;if(this.h[0] < this.h[1]){start = this.h[0];end = this.h[1]}else{start = this.h[1];end = this.h[0];};start=(360-start)*Math.PI/180;end=(360-end)*Math.PI/180;var w = 0.5*(scale_x_radius(this.w[0]));var wh = 0.5*(scale_y_radius(this.w[1]));ctx.scale(1,wh/w);ctx.arc(this.x[0],this.y[0]*w/wh,w,start,end,true);ctx.stroke();if(this.use_filled == 1){ ctx.fillStyle = this.fill_color;ctx.lineTo(this.x[0],this.y[0]);ctx.fill(); };ctx.restore();break;");break;
  131.     case 13: fprintf(js_include_file,"case 13: for(var p = 0; p < this.x.length; p++){ ctx.arc(this.x[p],this.y[p],scale_x_radius(this.w[p]),0,2*Math.PI,false);};break;");break;
  132.     case 14: fprintf(js_include_file,"case 14: if( this.font_family == null ){ ctx.font = this.font_size+\"px Ariel\";}else{ctx.font = this.font_family ;};if( this.use_once == true ){this.marge = 2*this.line_width;this.textwidth = ctx.measureText(this.text).width;this.textheight = ctx.measureText('W').width;};if( this.use_offset > 0 && this.use_once == true ){this.use_once = false;if(this.use_offset == 1){this.y[0] = this.y[0] - this.marge;}else{if(this.use_offset == 2){this.x[0] = this.x[0] + this.marge;}else{if(this.use_offset == 3){this.y[0] = this.y[0] - this.marge;this.x[0] = this.x[0] + this.marge;}else{if(this.use_offset == 4){this.y[0] = parseInt(this.y[0] + 0.25*(this.textheight));this.x[0] = parseInt(this.x[0] - 0.5*(this.textwidth));};};};};};ctx.fillText(this.text,this.x[0],this.y[0]);break;");break;
  133.     case 15: fprintf(js_include_file,"case 15: break;");break;
  134.     case 16: fprintf(js_include_file,"case 16: for(var p = 0; p < this.x.length;p++){ctx.fillRect( this.x[p], this.y[p],this.line_width,this.line_width );};break;");break;
  135.     case 17: fprintf(js_include_file,"case 17: ctx.save();var start;var end;if(this.h[0] < this.h[1]){start = this.h[0];end = this.h[1]}else{start = this.h[1];end = this.h[0];};start=2*Math.PI-start;end=2*Math.PI-end;var r = scale_x_radius(this.w[0]);ctx.arc(this.x[0], this.y[0], r,start,end,true);if(this.use_filled){ctx.lineTo(this.x[0],this.y[0]);ctx.fill();};ctx.restore();break;");break;
  136.     case 18: fprintf(js_include_file,"case 18: for(var p=0 ; p < this.x.length ;p=p+2){ctx.moveTo(this.x[p], this.y[p]);ctx.lineTo(this.x[p+1],this.y[p+1]);};break;");break;
  137.     case 19: fprintf(js_include_file,"case 19: ctx.arc(this.x[0],this.y[0],this.line_width,0,2*Math.PI,false);var E1 = y2px(px2y(this.y[0]) - this.h[0]);var E2 = y2px(px2y(this.y[0]) + this.w[0]);ctx.moveTo(this.x[0],E1);ctx.lineTo(this.x[0],E2);ctx.moveTo(this.x[0] - 2*(this.line_width),E1);ctx.lineTo(this.x[0] + 2*(this.line_width),E1);ctx.moveTo(this.x[0] - 2*(this.line_width),E2);ctx.lineTo(this.x[0] + 2*(this.line_width),E2);break;");break;
  138.     case 20: fprintf(js_include_file,"case 20: ctx.arc(this.x[0],this.y[0],this.line_width,0,2*Math.PI,false);var E1 = x2px(px2x(this.x[0]) - this.w[0]);var E2 = x2px(px2x(this.x[0]) + this.h[0]);ctx.moveTo(E1,this.y[0]);ctx.lineTo(E2,this.y[0]);ctx.moveTo(E1,this.y[0]-2*(this.line_width));ctx.lineTo(E1,this.y[0]+2*(this.line_width));ctx.moveTo(E2,this.y[0]-2*(this.line_width));ctx.lineTo(E2,this.y[0]+2*(this.line_width));break;");break;
  139.     case 21: fprintf(js_include_file,"case 21: drawCurvedArrow(ctx,this.x[0],this.y[0],this.x[1],this.y[1],this.x[2],this.y[2],this.h[0],this.h[1]);break;");break;
  140.     case 22: fprintf(js_include_file,"case 22: break;");break;
  141.     case 24: fprintf(js_include_file,"case 24: ctx.save();var start;var end;if(this.h[0] < this.h[1]){start = this.h[0];end = this.h[1]}else{start = this.h[1];end = this.h[0];};start=(360-start)*Math.PI/180;end=(360-end)*Math.PI/180;var w = 0.5*(scale_x_radius(this.w[0]));var wh = 0.5*(scale_y_radius(this.w[1]));ctx.scale(1,wh/w);var f = w/wh;ctx.arc(this.x[0],this.y[0]*f,w,start,end,true);ctx.stroke();var xh = this.x[0]+ w*Math.cos(start);var yh = f*(this.y[0]+ wh*Math.sin(start));var xh0 = this.x[0]+ w*Math.cos(start+0.1);var yh0 = f*(this.y[0]+ wh*Math.sin(start+0.1));draw_arrowhead(xh,yh,xh0,yh0,ctx);ctx.restore();break;");break;
  142.     case 25: fprintf(js_include_file,"case 25: ctx.save();var start;var end;if(this.h[0] < this.h[1]){start = this.h[0];end = this.h[1]}else{start = this.h[1];end = this.h[0];};start=(360-start)*Math.PI/180;end=(360-end)*Math.PI/180;var w = 0.5*(scale_x_radius(this.w[0]));var wh = 0.5*(scale_y_radius(this.w[1]));ctx.scale(1,wh/w);var f = w/wh;ctx.arc(this.x[0],this.y[0]*f,w,start,end,true);ctx.stroke();var xh = this.x[0]+ w*Math.cos(end);var yh = f*(this.y[0]+ wh*Math.sin(end));var xh0 = this.x[0]+ wh*Math.cos(end-0.1);var yh0 =  f*(this.y[0]+ wh*Math.sin(end-0.1));draw_arrowhead(xh,yh,xh0,yh0,ctx);ctx.restore();break;");break;
  143.     case 26: fprintf(js_include_file,"case 26: ctx.save();var start;var end;if(this.h[0] < this.h[1]){start = this.h[0];end = this.h[1]}else{start = this.h[1];end = this.h[0];};start=(360-start)*Math.PI/180;end=(360-end)*Math.PI/180;var w = 0.5*(scale_x_radius(this.w[0]));var wh = 0.5*(scale_y_radius(this.w[1]));ctx.scale(1,wh/w);var f = w/wh;ctx.arc(this.x[0],this.y[0]*f,w,start,end,true);ctx.stroke();var xh = this.x[0]+ w*Math.cos(start);var yh = f*(this.y[0]+ wh*Math.sin(start));var xh0 = this.x[0]+ w*Math.cos(start+0.1);var yh0 = f*(this.y[0]+ wh*Math.sin(start+0.1));draw_arrowhead(xh,yh,xh0,yh0,ctx);xh = this.x[0]+ w*Math.cos(end);yh = f*(this.y[0]+ wh*Math.sin(end));xh0 = this.x[0]+ wh*Math.cos(end-0.1);yh0 =  f*(this.y[0]+ wh*Math.sin(end-0.1));draw_arrowhead(xh,yh,xh0,yh0,ctx);ctx.restore();break;");break;
  144.  
  145.     default: break;
  146.   }
  147.  }
  148. }
  149.  
  150. fprintf(js_include_file,"};\
  151. if(this.use_filled > 0){ ctx.fill();}\
  152. if(this.use_dashed == 1 ){if( ctx.setLineDash ){ ctx.setLineDash([this.dashtype0,this.dashtype1]);}else{ ctx.mozDash = [this.dashtype0,this.dashtype1];};};\
  153. ctx.stroke();ctx.restore();\
  154. };");
  155.  
  156. if( use_dragstuff != 1 ){
  157.  fprintf(js_include_file,"\n/* add mouse -- object recognition stuff */ Shape.prototype.contains = function(mx, my){");
  158.  /* only rotate text (type=14) with canvas-own-transformation !! */
  159.  if( dragstuff[14] == 1){ fprintf(js_include_file,"if( this.type == 14 ){if( this.angle != 0 ){ var m_rot = rotate_mouse(mx,my,this);mx = m_rot.x;my = m_rot.y;};};");}
  160.  fprintf(js_include_file," var marge = 2*this.org_line_width;\
  161. switch(this.type){default:break;");
  162.  for( i=0; i < MAX_DRAGSTUFF; i++){
  163.   if( dragstuff[i] == 1 ){
  164.    switch(i){
  165.     case 1: fprintf(js_include_file,"case 1: for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;");break;
  166.     case 2: fprintf(js_include_file,"case 2: for(var p = 0 ; p < this.x.length; p++ ){if( Math.abs(distance(this.x[p],this.y[p],mx,my) ) < this.w[p] + 4*marge ){return p;break;};};break;");break;
  167.     case 3: fprintf(js_include_file,"case 3: for(var p = 0 ; p < this.x.length; p++ ){if( Math.abs(distance(this.x[p],this.y[p],mx,my) ) < scale_x_radius(this.w[p]) + marge ){return p;break;};};break;");break;
  168.     case 4: fprintf(js_include_file,"case 4: var diff;var q;var r;for(var p = 0 ; p < this.x.length-1; p = p+2  ){if( ((this.x[p+1] - this.x[p]) != 0)  && ((this.y[p+1]-this.y[p]) != 0) ){r = (this.y[p+1]-this.y[p])/(this.x[p+1]-this.x[p]);q = this.y[p] - (r)*(this.x[p]);diff = distance_to_line(r,q,mx,my);}else{if( (this.y[p+1]-this.y[p]) != 0 ){diff = Math.abs(this.x[p] - mx);}else{diff = Math.abs(this.y[p] - my);};};if( diff  < marge ){ return p;};}; break;");break;
  169.     case 5: fprintf(js_include_file,"case 5: marge = 2*marge;for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;");break;
  170.     case 6: fprintf(js_include_file,"case 6: marge = 0.5*this.w[0];for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;");break;
  171.     case 7: fprintf(js_include_file,"case 7: for(var p = 0 ; p < this.x.length; p++ ){if( (this.x[p] - this.w[p] <= mx) && (this.x[p] + this.w[p] >= mx) &&  (this.y[p] - this.h[p] <= my) && (this.y[p] + this.h[p] >= my) ){return p;};};break;");break;
  172.     case 8: fprintf(js_include_file,"case 8: var diff;var q;var r;for(var p = 0 ; p < this.x.length-1; p = p+2  ){if( ((this.x[p+1] - this.x[p]) != 0)  && ((this.y[p+1]-this.y[p]) != 0) ){r = (this.y[p+1]-this.y[p])/(this.x[p+1]-this.x[p]);q = this.y[p] - (r)*(this.x[p]);diff = distance_to_line(r,q,mx,my);}else{if( (this.y[p+1]-this.y[p]) != 0 ){diff = Math.abs(this.x[p] - mx);}else{diff = Math.abs(this.y[p] - my);};};if( diff  < marge ){ return p;};}; break;");break;
  173.     case 9: fprintf(js_include_file,"case 9: for(var p = 0 ; p < this.x.length; p++ ){if( (this.x[p] - this.line_width <= mx) && (this.x[p] + this.w[p] + this.line_width >= mx) &&  (this.y[p] - this.line_width <= my) && (this.y[p] + this.h[p] +this.line_width  >= my) ){return p;};};break;");break;
  174.     case 10: fprintf(js_include_file,"case 10: var diff;var q;var r;for(var p = 0 ; p < this.x.length-1; p = p+2  ){if( ((this.x[p+1] - this.x[p]) != 0)  && ((this.y[p+1]-this.y[p]) != 0) ){r = (this.y[p+1]-this.y[p])/(this.x[p+1]-this.x[p]);q = this.y[p] - (r)*(this.x[p]);diff = distance_to_line(r,q,mx,my);}else{if( (this.y[p+1]-this.y[p]) != 0 ){diff = Math.abs(this.x[p] - mx);}else{diff = Math.abs(this.y[p] - my);};};if( diff  < marge ){ return p;};}; break;");break;
  175.     case 11: fprintf(js_include_file,"case 11: break;");break;
  176.     case 12: fprintf(js_include_file,"case 12: var radius = 0.5*(scale_x_radius(this.w[0]));for(var p = 0 ; p < this.x.length; p++ ){var d = Math.abs(distance(this.x[p],this.y[p],mx,my));if( d < radius + marge && d > radius - marge ){return p;break;};};break;");break;
  177.     case 13: fprintf(js_include_file,"case 13: for(var p = 0 ; p < this.x.length; p++ ){if( Math.abs(distance(this.x[p],this.y[p],mx,my) ) < scale_x_radius(this.w[p]) + marge ){return p;break;};};break;");break;
  178.     case 14: fprintf(js_include_file,"case 14: for(var p = 0 ; p < this.x.length; p++ ){if( my < this.y[p] &&  my > this.y[p] - this.textheight ){if( mx < this.x[p] + this.textwidth && mx > this.x[p] ){ return p;break;};};};break;");break;
  179.     case 15: fprintf(js_include_file,"case 15: break;");break;
  180.     case 16: fprintf(js_include_file,"case 16: break;");break;
  181.     case 17: fprintf(js_include_file,"case 17: var radius = scale_x_radius(this.w[0]);var d = Math.abs(distance(this.x[0],this.y[0],mx,my));if( d < radius + marge && d > radius - marge ){return 0;break;};break;");break;
  182.     case 18: fprintf(js_include_file,"case 18: var diff;var q;var r;if(((this.x[1] - this.x[0]) != 0) && ((this.y[1]-this.y[0]) != 0)){r = (this.y[1]-this.y[0])/(this.x[1]-this.x[0]);q = this.y[0] - (r)*(this.x[0]);diff = distance_to_line(r,q,mx,my);}else{if((this.y[1]-this.y[0])!= 0){diff = Math.abs(this.x[0] - mx);}else{diff = Math.abs(this.y[0] - my);};};if( diff  < marge ){ return 0;};break;");break;
  183.     case 19: fprintf(js_include_file,"case 19: marge = 2*marge;for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;");break;
  184.     case 20: fprintf(js_include_file,"case 20: for(var p = 0 ; p < this.x.length; p++ ){if( (this.x[p] - this.line_width <= mx) && (this.x[p] + this.w[p] + this.line_width >= mx) &&  (this.y[p] - this.line_width <= my) &&(this.y[p] + this.h[p] +this.line_width  >= my) ){return p;};};break;");break;
  185.     case 21: fprintf(js_include_file,"case 21: marge = 2*marge;for(var p = 0 ; p < this.x.length; p++ ){if( mx < this.x[p] + marge &&  mx > this.x[p] - marge ){if( my < this.y[p]+marge && my > this.y[p] - marge ){return p;};};};break;");break;
  186.     case 22: fprintf(js_include_file,"case 22: break;");break;
  187.     case 24: fprintf(js_include_file,"case 24: var radius = 0.5*(scale_x_radius(this.w[0]));for(var p = 0 ; p < this.x.length; p++ ){var d = Math.abs(distance(this.x[p],this.y[p],mx,my));if( d < radius + marge && d > radius - marge ){return p;break;};};break;");break;
  188.     case 25: fprintf(js_include_file,"case 25: var radius = 0.5*(scale_x_radius(this.w[0]));for(var p = 0 ; p < this.x.length; p++ ){var d = Math.abs(distance(this.x[p],this.y[p],mx,my));if( d < radius + marge && d > radius - marge ){return p;break;};};break;");break;
  189.     case 26: fprintf(js_include_file,"case 26: var radius = 0.5*(scale_x_radius(this.w[0]));for(var p = 0 ; p < this.x.length; p++ ){var d = Math.abs(distance(this.x[p],this.y[p],mx,my));if( d < radius + marge && d > radius - marge ){return p;break;};};break;");break;
  190.     default: break;
  191.    }
  192.   }
  193.  }
  194.  fprintf(js_include_file,"};return -1;};\
  195. if( typeof(slidergroup) !== 'object' ){ var slidergroup = [];};\
  196. var obj = create_canvas%d(%d,xsize,ysize);\
  197. var container_div = document.getElementById(\"canvas_div%d\");\
  198. function CanvasState(canvas,container_div){\
  199.  this.canvas = canvas;this.width = canvas.width;this.height = canvas.height;var ctx = canvas.getContext(\"2d\");this.ctx = ctx;this.valid = false;this.shapes = [];this.moved = [];this.dragging = false;this.selection = null;var myState = this;\
  200.  container_div.addEventListener( 'mouseup'    , mouseup,  false);\
  201.  container_div.addEventListener( 'mousemove'  , mousemove,false);\
  202.  container_div.addEventListener( 'mousedown'  , mousedown,false);\
  203.  container_div.addEventListener('touchstart'  , function(e) { e.preventDefault(); mousedown(e.changedTouches[0]);},false);\
  204.  container_div.addEventListener( 'touchmove'  , function(e) { e.preventDefault(); mousemove(e.changedTouches[0]);},false);\
  205.  container_div.addEventListener( 'touchend'   , function(e) { e.preventDefault(); mouseup(  e.changedTouches[0]);},false);\
  206.  function mousedown(e){if( wims_status == \"done\"){return null;};var mouse = getMouse(e,canvas);var mx = mouse.x;var my = mouse.y;var shapes = myState.shapes;var l = shapes.length;var chk = -1;for(var i=0;i<l;i++){chk = shapes[i].contains(mx, my);if ( chk != -1 ){if( myState.shapes[i].use_slider[0] != -1 ){if( slidergroup[shapes[i].object_cnt] == null ){slidergroup[shapes[i].object_cnt] = shapes[i];}else{slidergroup[shapes[i].object_cnt] = null;};};myState.chk = chk;myState.selection = shapes[i];myState.valid = false;switch(shapes[i].onclick){case 0:myState.dragging = false;break;case 1:if( dragdrop_reply[myState.selection.object_cnt].clicked != 1 ){myState.selection.line_width = 2*myState.selection.org_line_width;myState.selection.font_family = parseInt(myState.selection.font_size+10)+\"px Courier\";dragdrop_reply[myState.selection.object_cnt].clicked = 1;}else{dragdrop_reply[myState.selection.object_cnt].clicked = 0;myState.selection.font_family = myState.selection.org_font_family;myState.selection.line_width = myState.selection.org_line_width;};myState.dragging = false;myState.draw();myState.selection = null;break;\
  207.  case 2: myState.dragging = true;break;\
  208.  case 3: break;\
  209.  case 4: break;\
  210.  case 5: myState.dragging = true;break;\
  211.  default:break;};myState.valid = true;return;};};myState.valid = true;return;};\
  212.  function mouseup(e){if(myState.selection != null ){if(myState.selection.onclick == 2 ){var dx,dy;var mouse = getMouse(e,canvas);var xy = multisnap_check(mouse.x,mouse.y,myState.selection.use_snap);switch(myState.selection.drag_type){case 0: dx = xy[0] - myState.selection.x[myState.chk];dy = xy[1] - myState.selection.y[myState.chk];break;case 1: dx = xy[0] - myState.selection.x[myState.chk];dy = 0;break;case 2: dx = 0;dy = xy[1] - myState.selection.y[myState.chk];break;default:break;};myState.selection = move(myState.selection,dx,dy);dragdrop_reply[myState.selection.object_cnt] = {object_cnt:myState.selection.object_cnt,type:myState.selection.onclick,x:myState.selection.x[0],y:myState.selection.y[0],r:myState.selection.w[0],angle:myState.selection.angle};myState.valid = false;myState.draw();myState.valid = true;};};myState.selection = null;myState.dragging = false;};\
  213.  function mousemove(e){if(myState.dragging && e.button == 0 ){var dx,dy;var mouse = getMouse(e,canvas);var xy = multisnap_check(mouse.x,mouse.y,myState.selection.use_snap);switch(myState.selection.drag_type){case 0: dx = xy[0] - myState.selection.x[myState.chk];dy = xy[1] - myState.selection.y[myState.chk];break;case 1: dx = xy[0] - myState.selection.x[myState.chk];dy = 0;break;case 2: dx = 0;dy = xy[1] - myState.selection.y[myState.chk];break;default:break;};myState.selection = move(myState.selection,dx,dy);};myState.valid = false;};this.interval = 30;setInterval(function() { myState.draw(); }, myState.interval);\
  214. };\
  215. CanvasState.prototype.addShape = function(shape){if( shape.type == 17 || shape.type == 12 || shape.onclick > 3 ){ slidergroup[shape.object_cnt] = shape;};this.shapes.push(shape);this.valid = false;};\
  216. CanvasState.prototype.clear = function(){this.ctx.clearRect(0, 0, this.width, this.height);};\
  217. CanvasState.prototype.draw = function(){if(this.valid == false ){var shapes = this.shapes;this.clear();var l = shapes.length;var shape;for(var i = 0; i < l; i++){shape = shapes[i];shape.draw(this.ctx);};this.valid = true;};};var dragstuff = new CanvasState(obj,container_div);\
  218. ",canvas_root_id,DRAG_CANVAS,canvas_root_id);
  219.  
  220.  if( reply_format != -1 ){
  221.  /*
  222.  dragdrop + onclick for 'dragstuff', command 'copy' and external 'xml/mathml/javascript objects'
  223.  only the FIRST x,y value-pair is used for the reply !!
  224.  */
  225.   if(reply_format == 100){/* this reply is raw javascript giving ALL object/properties */
  226.    fprintf(js_include_file,"\n/* add reply stuff  */\
  227.   CanvasState.prototype.read_dragdrop = function(){\
  228.    if( wims_status == 'done' || use_dragdrop_reply == -1 ){return null;};\
  229.    var obj = dragstuff.shapes;\
  230.    var total = '';var rep = '';\
  231.    Object.getOwnPropertyNames(obj).forEach(\
  232.     function(val, idx, array){ var tmp = obj[val];\
  233.      Object.getOwnPropertyNames(tmp).forEach(\
  234.       function(val, idx, array){\
  235.        rep = rep+':'+val+'='+tmp[val]+'\\t';\
  236.       }\
  237.      )\
  238.      total = total+tmp['object_cnt']+rep+'\\n';rep='';\
  239.     }\
  240.    );\
  241.    return total;\
  242.   };read_dragdrop%d = dragstuff.read_dragdrop;",canvas_root_id);
  243.   }else{
  244.    fprintf(js_include_file,"\n/* add reply stuff  */\
  245.   function set_precision(val){val = (Math.round(dragdrop_precision*val))/dragdrop_precision;if(Number.isNaN(val) ){return 'NaN';}else{return val;};};\
  246.   CanvasState.prototype.read_dragdrop = function(){\
  247.    if( wims_status == \"done\" || use_dragdrop_reply == -1 ){return null;};\
  248.    var len = dragdrop_reply.length;\
  249.    var idx,x,y;\
  250.    var total = new Array();\
  251.    for(var p = 0 ; p < len ; p++){\
  252.    var obj = dragdrop_reply[p];\
  253.     idx = obj.object_cnt;\
  254.     if( typeof(idx) === 'number' ){\
  255.      if(obj.type == 1){\
  256.       total[idx] = obj.clicked;\
  257.      }else{\
  258.       if(obj.type !=0 ){\
  259.        if( typeof(obj.x) === 'number' ){x = obj.x;}else{x = obj.x[0];};\
  260.        if( typeof(obj.y) === 'number' ){y = obj.y;}else{y = obj.y[0];};\
  261.        total[idx] = set_precision(px2x(x))+':'+set_precision(px2y(y))+':'+obj.r+':'+set_precision(obj.angle);\
  262.       };\
  263.      };\
  264.     };\
  265.    };\
  266.    return total;\
  267.   };read_dragdrop%d = dragstuff.read_dragdrop;",canvas_root_id);
  268.   }
  269.  
  270.   }
  271.  }
  272.  else /* use_dragstuff == 1 : no mouse code ! */
  273.  {
  274.   fprintf(js_include_file,"\n/* no mouse actions needed  */\
  275.  var container_div = document.getElementById(\"canvas_div%d\");\
  276.  function CanvasState(canvas,container_div){this.canvas = canvas;this.width = canvas.width;this.height = canvas.height;var ctx = canvas.getContext(\"2d\");this.ctx = ctx;this.shapes = [];this.moved = [];this.dragging = false;this.selection = null;this.draw();};\
  277.  CanvasState.prototype.addShape = function(shape){this.shapes.push(shape);this.draw();};\
  278.  CanvasState.prototype.clear = function(){this.ctx.clearRect(0, 0, this.width, this.height);};\
  279.  CanvasState.prototype.draw = function(){var shapes = this.shapes;this.clear();var l = shapes.length;var shape;for(var i = 0; i < l; i++){shape = shapes[i];shape.draw(this.ctx);};};var obj = create_canvas%d(%d,xsize,ysize);\
  280.  var dragstuff = new CanvasState(obj,container_div);",canvas_root_id,canvas_root_id,DRAG_CANVAS);
  281.   if(reply_format != -1 ){ fprintf(js_include_file,"\n/* add reply stuff  */read_dragdrop%d = dragstuff.read_dragdrop;\n",canvas_root_id);}
  282.  }
  283. }
  284.  
  285.