_window.c
Upload User: gzelex
Upload Date: 2007-01-07
Package Size: 707k
Code Size: 17k
Development Platform:

MultiPlatform

  1. /*******************************************************************************
  2. +
  3. +  LEDA-R  3.2.3
  4. +
  5. +  _window.c
  6. +
  7. +  Copyright (c) 1995  by  Max-Planck-Institut fuer Informatik
  8. +  Im Stadtwald, 66123 Saarbruecken, Germany     
  9. +  All rights reserved.
  10. *******************************************************************************/
  11. #include <LEDA/window.h>
  12. #include <math.h>
  13. //------------------------------------------------------------------------------
  14. // WINDOW BASICS
  15. //------------------------------------------------------------------------------
  16. static void window_error_handler(int i, const char* s)
  17.   panel P;
  18.   if (i == 0)
  19.   { P.text_item(string("WARNING: %s",i,s));
  20.     P.button("ok");
  21.     P.open();
  22.     return;
  23.    }
  24.   P.text_item(string("ERROR(%d): %s",i,s));
  25.   P.button("exit");
  26.   P.button("dump core");
  27.   if (P.open() == 0)
  28.      exit(0);
  29.   else 
  30.      abort();
  31.  }
  32. window::window(float width,float height,float xpos,float ypos,const char* label)
  33. : LEDA_WINDOW(width,height,xpos,ypos, label)
  34. { set_error_handler(window_error_handler); }
  35. window::window(float width, float height, const char* label)
  36. : LEDA_WINDOW(width,height,label)
  37. { set_error_handler(window_error_handler); }
  38. window::window(const char* label) : LEDA_WINDOW(label)
  39. { set_error_handler(window_error_handler); }
  40. window::window(int) // do not open
  41. { set_error_handler(window_error_handler); }
  42. //------------------------------------------------------------------------------
  43. // WINDOW OUTPUT
  44. //------------------------------------------------------------------------------
  45. // pixels
  46. void window::draw_pix(double x, double y, color c ) 
  47. { LEDA_WINDOW::draw_pix(x,y,c); }
  48. void window::draw_pix(const point& p, color c ) 
  49. { draw_pix(p.xcoord(),p.ycoord(),c); }
  50. void window::draw_text(double x, double y, string s, color c)
  51. { LEDA_WINDOW::draw_text(x,y,s,c); }
  52. void window::draw_text(const point& p, string s, color c)
  53. { draw_text(p.xcoord(),p.ycoord(),s,c); }
  54. void window::draw_ctext(double x, double y, string s, color c)
  55. { LEDA_WINDOW::draw_ctext(x,y,s,c); }
  56. void window::draw_ctext(const point& p, string s, color c)
  57. { draw_ctext(p.xcoord(),p.ycoord(),s,c); }
  58. // points
  59. void window::draw_point(double x0,double y0,color c)
  60. { LEDA_WINDOW::draw_point(x0,y0,c); }
  61. void window::draw_point(const point& p,color c)
  62. { draw_point(p.xcoord(),p.ycoord(),c); }
  63. // segments
  64. void window::draw_segment(double x1, double y1, double x2, double y2, color c )
  65. { LEDA_WINDOW::draw_segment(x1,y1,x2,y2,c); }
  66. void window::draw_segment(const point& p, const point& q, color c )
  67. { window::draw_segment(p.xcoord(),p.ycoord(),q.xcoord(),q.ycoord(),c); }
  68. void window::draw_segment(const segment& s, color c )
  69. { draw_segment(s.start(),s.end(),c); }
  70. // lines
  71. void window::draw_line(const line& l, color c )
  72. {
  73.   double a,x0,x1,y0,y1;
  74.   if (l.vertical()) 
  75.   { draw_vline(l.x_proj(0),c);
  76.     return;
  77.    }
  78.   a = l.slope();
  79.   if (fabs(a) < 1)
  80.   { x0 = xmin();
  81.     x1 = xmax();
  82.     y0 = l.y_proj(x0);
  83.     y1 = l.y_proj(x1);
  84.    }
  85.   else
  86.   { y0 = ymin();
  87.     y1 = ymax();
  88.     x0 = l.x_proj(y0);
  89.     x1 = l.x_proj(y1);
  90.    }
  91.   LEDA_WINDOW::draw_segment(x0,y0,x1,y1,c);
  92. }
  93. void window::draw_line(const segment& s, color c )
  94. { draw_line(line(s),c); }
  95. void window::draw_line(const point& p, const point& q, color c) 
  96. { draw_line(line(p,q),c); }
  97. void window::draw_line(double x1, double y1, double x2, double y2, color c )
  98. { draw_line(segment(x1,y1,x2,y2),c); }
  99. void window::draw_hline(double y, color c )
  100. { LEDA_WINDOW::draw_segment(xmin(),y,xmax(),y,c); }
  101. void window::draw_vline(double x, color c )
  102. { LEDA_WINDOW::draw_segment(x,ymin(),x,ymax(),c); }
  103. // nodes
  104. void window::draw_node(double x0,double y0,color c) 
  105. { LEDA_WINDOW::draw_node(x0,y0,c); }
  106. void window::draw_node(const point& p, color c)
  107. { window::draw_node(p.xcoord(),p.ycoord(),c); }
  108. void window::draw_filled_node(double x0,double y0,color c)
  109. { LEDA_WINDOW::draw_filled_node(x0,y0,c); }
  110. void window::draw_filled_node(const point& p, color c)
  111. { window::draw_filled_node(p.xcoord(),p.ycoord(),c); }
  112. void window::draw_text_node(double x,double y,string s,color c)
  113. { LEDA_WINDOW::draw_text_node(x,y,~s,c); }
  114. void window::draw_text_node(const point& p ,string s,color c)
  115. { window::draw_text_node(p.xcoord(),p.ycoord(),~s,c); }
  116. void window::draw_int_node(double x,double y,int i,color c)
  117. { LEDA_WINDOW::draw_int_node(x,y,i,c); }
  118. void window::draw_int_node(const point& p ,int i,color c)
  119. { window::draw_int_node(p.xcoord(),p.ycoord(),i,c); }
  120. //circles
  121. void window::draw_circle(double x,double y,double r,color c)
  122. { LEDA_WINDOW::draw_circle(x,y,r,c); }
  123. void window::draw_circle(const point& p,double r,color c)
  124. { LEDA_WINDOW::draw_circle(p.xcoord(),p.ycoord(),r,c); }
  125. void window::draw_circle(const circle& C,color c)
  126. { point p = C.center();
  127.   double r = C.radius();
  128.   LEDA_WINDOW::draw_circle(p.xcoord(),p.ycoord(),r,c); 
  129.  }
  130. // discs
  131. void window::draw_disc(double x,double y,double r,color c)
  132. { LEDA_WINDOW::draw_filled_circle(x,y,r,c); }
  133. void window::draw_disc(const point& p,double r,color c)
  134. { window::draw_disc(p.xcoord(),p.ycoord(),r,c); }
  135. void window::draw_disc(const circle& C,color c)
  136. { draw_disc(C.center(),C.radius(),c); }
  137. //ellipses
  138. void window::draw_ellipse(double x,double y,double r1,double r2,color c)
  139. { LEDA_WINDOW::draw_ellipse(x,y,r1,r2,c); }
  140. void window::draw_ellipse(const point& p, double r1, double r2, color c)
  141. { LEDA_WINDOW::draw_ellipse(p.xcoord(),p.ycoord(),r1,r2,c); }
  142. void window::draw_filled_ellipse(double x,double y,double r1,double r2,color c)
  143. { LEDA_WINDOW::draw_filled_ellipse(x,y,r1,r2,c); }
  144. void window::draw_filled_ellipse(const point& p, double r1, double r2, color c)
  145. { LEDA_WINDOW::draw_filled_ellipse(p.xcoord(),p.ycoord(),r1,r2,c); }
  146. // arcs
  147. void window::draw_arc(const segment& s, double r, color col)
  148. { double d   = s.length()/(2*fabs(r));
  149.   if (d > 1) return;
  150.   double acd = acos(d);
  151.   if (r < 0) 
  152.     { point   m  = s.start().translate(s.angle()-acd,-r);
  153.       segment x(m,s.end());
  154.       LEDA_WINDOW::draw_arc(m.xcoord(),m.ycoord(),-r,-r,x.angle(),LEDA_PI-2*acd,col);
  155.      }
  156.   else 
  157.     { point   m  = s.start().translate(s.angle()+acd,r);
  158.       segment x(m,s.end());
  159.       LEDA_WINDOW::draw_arc(m.xcoord(),m.ycoord(),r,r,x.angle(),2*acd-LEDA_PI,col);
  160.      }
  161.  }
  162. void window::draw_arc(double x0,double y0,double x1,double y1,double r,color c)
  163. { draw_arc(segment(x0,y0,x1,y1),r,c); }
  164. void window::draw_arc(const point& p, const point& q, double r, color c)
  165. { draw_arc(segment(p,q),r,c); }
  166. void window::draw_arc_arrow(const segment& s, double r, color col)
  167. { double d   = s.length()/(2*r);
  168.   if (d > 1) return;
  169.   point p = draw_arrow_head(s.end(), s.angle() + LEDA_PI_2 - acos(d), col);
  170.   draw_arc(s.start(),p,r,col);
  171.  }
  172. void window::draw_arc_arrow(double x0,double y0,double x1,double y1,double r,color c)
  173. { draw_arc_arrow(segment(x0,y0,x1,y1),r,c); }
  174. void window::draw_arc_arrow(const point& p, const point& q, double r, color c)
  175. { draw_arc_arrow(segment(p,q),r,c); }
  176. // polygons
  177. void window::draw_polygon(const list<point>& lp, color c)
  178. { int n = lp.length();
  179.   double* X = new double[n];
  180.   double* Y = new double[n];
  181.   n = 0;
  182.   point p;
  183.   forall(p,lp) 
  184.   { X[n] = p.xcoord();
  185.     Y[n] = p.ycoord();
  186.     n++;
  187.    }
  188.   LEDA_WINDOW::draw_polygon(n,X,Y,c);
  189.   delete X;
  190.   delete Y;
  191. }
  192. void window::draw_filled_polygon(const list<point>& lp, color c)
  193. { int n = lp.length();
  194.   double* X = new double[n];
  195.   double* Y = new double[n];
  196.   n = 0;
  197.   point p;
  198.   forall(p,lp) 
  199.   { X[n] = p.xcoord();
  200.     Y[n] = p.ycoord();
  201.     n++;
  202.    }
  203.   LEDA_WINDOW::draw_filled_polygon(n,X,Y,c);
  204.   delete X;
  205.   delete Y;
  206. }
  207. void window::draw_polygon(const polygon& P, color c )
  208. { draw_polygon(P.vertices(),c); }
  209. void window::draw_filled_polygon(const polygon& P,color c )
  210. { draw_filled_polygon(P.vertices(),c); }
  211. void window::draw_rectangle(double a, double  b, double c, double d, color col)
  212. { LEDA_WINDOW::draw_rectangle(a,b,c,d,col); }
  213. void window::draw_filled_rectangle(double a, double  b, double c, double d, color col)
  214. { LEDA_WINDOW::draw_filled_rectangle(a,b,c,d,col); }
  215. // functions
  216. void window::plot_xy(double x0, double x1, draw_func_ptr f, color c)
  217. { LEDA_WINDOW::plot_xy(x0,x1,f,c); }
  218. void window::plot_yx(double y0, double y1, draw_func_ptr f, color c)
  219. { LEDA_WINDOW::plot_yx(y0,y1,f,c); }
  220. // arrows
  221. point window::draw_arrow_head(const point& q, double a, color c)
  222. { double X[4];
  223.   double Y[4];
  224.   
  225.   double alpha = a-LEDA_PI; 
  226.   double d = 2*((get_line_width()+2)/3.0)/scale();
  227.   point l = q.translate(alpha+LEDA_PI/6, 7*d);
  228.   point m = q.translate(alpha,        4*d);
  229.   point r = q.translate(alpha-LEDA_PI/6, 7*d);
  230.   X[0] = q.xcoord();
  231.   Y[0] = q.ycoord();
  232.   X[1] = l.xcoord();
  233.   Y[1] = l.ycoord();
  234.   X[2] = m.xcoord();
  235.   Y[2] = m.ycoord();
  236.   X[3] = r.xcoord();
  237.   Y[3] = r.ycoord();
  238.   LEDA_WINDOW::draw_filled_polygon(4,X,Y,c);
  239.   return m;
  240. }
  241. void window::draw_arrow(const segment& s, color c)
  242. { point q = draw_arrow_head(s.end(),s.angle(),c);
  243.   draw_segment(s.start(),q,c);
  244. }
  245. void window::draw_arrow(const point& p, const point& q, color c)
  246. { draw_arrow(segment(p,q),c); }
  247. void window::draw_arrow(double x0, double y0, double x1, double y1, color c)
  248. { draw_arrow(segment(x0,y0,x1,y1),c); }
  249. // edges
  250. void window::draw_edge(double x0, double y0, double x1, double y1, color c)
  251. { LEDA_WINDOW::draw_edge(x0,y0,x1,y1,c); }
  252. void window::draw_edge(const point& p, const point& q, color c)
  253. { draw_edge(p.xcoord(),p.ycoord(),q.xcoord(),q.ycoord(),c); }
  254. void window::draw_edge(const segment& s, color c)
  255. { draw_edge(s.start(),s.end(),c); }
  256. void window::draw_arc_edge(double x0, double y0, double x1, double y1, color c)
  257. { draw_arc_edge(segment(x0,y0,x1,y1),c); }
  258. void window::draw_arc_edge(const point& p, const point& q, double r, color c)
  259. { draw_arc_edge(segment(p,q),r,c); }
  260. void window::draw_arc_edge(const segment& s, double r, color c)
  261. { double R = get_node_width()/scale();
  262.   double d = s.length()/(2*r);
  263.   if (d > 1) return;
  264.   point p = s.start().translate(s.angle() - LEDA_PI_2 + acos(d), R);
  265.   point q = s.end().translate(s.angle() + LEDA_PI_2 - acos(d),  -R);
  266.   draw_arc(p,q,r,c);
  267.  }
  268. void window::draw_edge_arrow(double x0,double y0,double x1,double y1,color c)
  269. { draw_edge_arrow(segment(x0,y0,x1,y1),c); }
  270. void window::draw_edge_arrow(const point& p, const point& q, color c)
  271. { draw_edge_arrow(segment(p,q),c); }
  272. void window::draw_edge_arrow(const segment& s, color c)
  273. { double  alpha = s.angle();
  274.   point p = s.start().translate(alpha,get_node_width()/scaling);
  275.   point q = s.end().translate(alpha,-get_node_width()/scaling);
  276.   draw_arrow(p,q,c);
  277. }
  278. void window::draw_arc_edge_arrow(double x,double y,double x1,double y1,color c)
  279. { draw_arc_edge_arrow(segment(x,y,x1,y1),c); }
  280. void window::draw_arc_edge_arrow(const point& p, const point& q, double r, color c)
  281. { draw_arc_edge_arrow(segment(p,q),r,c); }
  282. void window::draw_arc_edge_arrow(const segment& s, double r, color c)
  283. { double R = get_node_width()/scale();
  284.   double d = s.length()/(2*r);
  285.   if (d > 1) return;
  286.   point p = s.start().translate(s.angle() - LEDA_PI_2 + acos(d), R);
  287.   point q = s.end().translate(s.angle() + LEDA_PI_2 - acos(d),  -R);
  288.   draw_arc_arrow(p,q,r,c);
  289.  }
  290. //------------------------------------------------------------------------------
  291. // WINDOW INPUT
  292. //------------------------------------------------------------------------------
  293. int window::get_button() 
  294. { double x,y;
  295.   return LEDA_WINDOW::get_button(x,y); 
  296.  }
  297. int window::get_button(double& x, double& y) 
  298. { return LEDA_WINDOW::get_button(x,y); }
  299. int  window::get_button(point& q)
  300. { double x,y;
  301.   int key = LEDA_WINDOW::get_button(x,y);
  302.   q = point(x,y);
  303.   return key;
  304.  }
  305. int window::read_mouse()
  306. { double d;
  307.   return LEDA_WINDOW::read_mouse(0,0.0,0.0,d,d);
  308.  }
  309. int  window::read_mouse(double& x, double& y)
  310. { return LEDA_WINDOW::read_mouse(0,0.0,0.0,x,y); }
  311. int  window::read_mouse(point& q)
  312. { double x,y;
  313.   int key = LEDA_WINDOW::read_mouse(0,0.0,0.0,x,y);
  314.   q = point(x,y);
  315.   return key;
  316.  }
  317. int  window::read_mouse_seg(double x0, double y0, double& x, double& y)
  318. { return LEDA_WINDOW::read_mouse(1,x0,y0,x,y); }
  319. int  window::read_mouse_seg(const point& p, point& q)
  320. { double X,Y;
  321.   int key = LEDA_WINDOW::read_mouse(1,p.xcoord(),p.ycoord(),X,Y);
  322.   q = point(X,Y);
  323.   return key;
  324. }
  325. int  window::read_mouse_rect(double x0, double y0, double& x, double& y)
  326. { return LEDA_WINDOW::read_mouse(2,x0,y0,x,y); }
  327. int  window::read_mouse_rect(const point& p, point& q)
  328. { double X,Y;
  329.   int key = LEDA_WINDOW::read_mouse(2,p.xcoord(),p.ycoord(),X,Y);
  330.   q = point(X,Y);
  331.   return key;
  332. }
  333. int  window::read_mouse_circle(double x0, double y0, double& x, double& y)
  334. { return LEDA_WINDOW::read_mouse(3,x0,y0,x,y); }
  335. int  window::read_mouse_circle(const point& p, point& q)
  336. { double X,Y;
  337.   int key = LEDA_WINDOW::read_mouse(3,p.xcoord(),p.ycoord(),X,Y);
  338.   q = point(X,Y);
  339.   return key;
  340. }
  341. int window::read_mouse_action(mouse_action_func_ptr f, double& x, double& y)
  342. { return LEDA_WINDOW::read_mouse_action(f,0.0,0.0,x,y); }
  343. int window::read_mouse_action(mouse_action_func_ptr f, point& q)
  344. { double X,Y;
  345.   int key = LEDA_WINDOW::read_mouse_action(f,0.0,0.0,X,Y);
  346.   q = point(X,Y);
  347.   return key;
  348. }
  349. window& window::read(point& p)
  350. { double x,y;
  351.   state = 1;
  352.   int k;
  353.   while ((k = read_mouse(x,y)) != 1) 
  354.    if (k == 3) 
  355.     { state = 0;
  356.       return *this;
  357.      }
  358.   p = point(x,y);
  359.   return *this;
  360.  }
  361. window& window::read(segment& s)
  362. { double x,y;
  363.   point p;
  364.   int key = 0;
  365.   state = 1;
  366.   if (!read(p).state) 
  367.    return *this;
  368.   while ((key=read_mouse_seg(p.xcoord(),p.ycoord(),x,y)) != 1)
  369.   { if (key== 3)  
  370.      { state = 0;
  371.        break; 
  372.       }
  373.     if (key==-1)
  374.       if (!read(p).state) break;
  375.    }
  376.    if (state) s = segment(p.xcoord(),p.ycoord(),x,y);
  377.   return *this;
  378. }
  379. window& window::read(line& l)
  380. { segment s;
  381.   state = 1;
  382.   read(s);
  383.   if (state) l = line(s);
  384.   return *this;
  385.  }
  386. window& window::read(circle& c)
  387. { double x,y;
  388.   point p;
  389.   int key = 0;
  390.   state = 1;
  391.   if (!read(p).state) 
  392.    return *this;
  393.   drawing_mode save = set_mode(xor_mode);
  394.   draw(p);
  395.   while ((key=read_mouse_circle(p.xcoord(),p.ycoord(),x,y)) != 1)
  396.   { if (key== 3)  
  397.      { state = 0;
  398.        break; 
  399.       }
  400.     if (key==-1)
  401.     { draw(p);
  402.       if (!read(p).state) break;
  403.       draw(p);
  404.      }
  405.    }
  406.    if (state) 
  407.    { double dx = x-p.xcoord();
  408.      double dy = y-p.ycoord();
  409.      c = circle(p,sqrt(dx*dx+dy*dy));
  410.      draw(p);
  411.     }
  412.   set_mode(save);
  413.   return *this;
  414. }
  415. window& window::read(polygon& P)
  416. { double x,y;
  417.   int key = 0;
  418.   state = 1;
  419.   point first,last,p;
  420.   list<point> pl;
  421.   if (!read(first).state) return *this;
  422.   pl.append(first);
  423.   p = first;
  424.   drawing_mode save = set_mode(xor_mode);
  425.   while ((key = read_mouse_seg(p.xcoord(),p.ycoord(),x,y)) !=2)
  426.   { 
  427.     if (key==3) break;
  428.     if (key==-1 && pl.length() > 1 ) 
  429.     { point l = pl.Pop();
  430.       draw_segment(pl.tail(),l);
  431.       p = pl.tail();
  432.      }
  433.     if (key==1)
  434.     { point q(x,y);
  435.       draw_segment(p,q);
  436.       pl.append(q);
  437.       p = q;
  438.      }
  439.   }
  440.   draw_segment(first,p);
  441.   list_item it;
  442.   forall_items(it,pl) draw_segment(pl[it],pl[pl.cyclic_succ(it)]);
  443.   if (key!=3)
  444.      P = polygon(pl);
  445.   else 
  446.      state = 0;
  447.   set_mode(save);
  448.   return *this;
  449. }
  450. window& window::operator>>(point& p)    
  451. { set_frame_label(">> POINT");
  452.   read(p); 
  453.   reset_frame_label();
  454.   return *this; 
  455.  }
  456. window& window::operator>>(segment& s)  
  457. { set_frame_label(">> SEGMENT");
  458.   read(s); 
  459.   reset_frame_label();
  460.   return *this; 
  461.  }
  462. window& window::operator>>(line& l)     
  463. { set_frame_label(">> LINE");
  464.   read(l); 
  465.   reset_frame_label();
  466.   return *this; 
  467.  }
  468. window& window::operator>>(circle& C)   
  469. { set_frame_label(">> CIRCLE");
  470.   read(C); 
  471.   reset_frame_label();
  472.   return *this; 
  473.  }
  474. window& window::operator>>(polygon& P)  
  475. { set_frame_label(">> POLYGON");
  476.   read(P); 
  477.   reset_frame_label();
  478.   return *this; 
  479.  }
  480. int window::confirm(string s)
  481. { panel p;
  482.   p.text_item(s);
  483.   p.button("YES");
  484.   p.button("NO");
  485.   return 1 - p.open();
  486. }
  487. void window::acknowledge(string s)
  488. { panel p;
  489.   p.text_item(s);
  490.   p.button("CONTINUE");
  491.   p.open();
  492. }
  493. void window::notice(string s)
  494. { panel p;
  495.   p.text_item(s);
  496.   p.button("CONTINUE");
  497.   p.open();
  498. }
  499. int  window::read_panel(string header, int n, string* L)
  500. { panel P("LEDA PANEL");
  501.   P.text_item(header);
  502.   for(int i = 0; i < n; i++) P.button(L[i]);
  503.   return P.open();
  504.  }
  505. int  window::read_vpanel(string header, int n, string* L)
  506. { panel P("LEDA PANEL");
  507.   P.text_item(header);
  508.   for(int i = 0; i < n; i++) 
  509.   { P.button(L[i]);
  510.     P.new_button_line();
  511.    }
  512.   return P.open();
  513.  }
  514. string  window::read_string(string prompt)
  515. { panel P("STRING INPUT PANEL");
  516.   string s;
  517.   P.string_item(prompt,s);
  518.   P.open();
  519.   return s;
  520.  }
  521. int  window::read_int(string prompt)
  522. { panel P("INT INPUT PANEL");
  523.   int i = 0;
  524.   P.int_item(prompt,i);
  525.   P.open();
  526.   return i;
  527. }
  528. double  window::read_real(string prompt)
  529. { panel P("DOUBLE INPUT PANEL");
  530.   double x = 0;
  531.   P.real_item(prompt,x);
  532.   P.open();
  533.   return x;
  534.  }