home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / diverses / leda / src / graphics / _graph_e.c next >
Encoding:
C/C++ Source or Header  |  1991-11-15  |  7.8 KB  |  366 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  2.1.1                                                 11-15-1991
  4. +
  5. +
  6. +  _graph_edit.c
  7. +
  8. +
  9. +  Copyright (c) 1991  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/graph_edit.h>
  16. #include <LEDA/d_array.h>
  17.  
  18. declare2(d_array,point,node)
  19. declare2(d_array,node,int)
  20.  
  21. declare(node_array,node)
  22.  
  23. static window*           Wp;
  24. static GRAPH(point,int)* Gp;
  25.  
  26. static int node_count = 0;
  27.  
  28. static d_array(point,node)   V(nil);
  29. static d_array(node,int)     name;
  30.  
  31.  
  32. //static int   node_width = 12;
  33. //static int   edge_width = 1;
  34.  
  35. static color node_color = blue;
  36. static color edge_color = red;
  37. static int   grid_size  =  50;
  38.  
  39. static bool  directed;
  40.  
  41.  
  42. static void draw_node_cursor(double x, double y)
  43. { Wp->draw_node(x,y); }
  44.  
  45.  
  46. static void draw_node(node v)
  47. { Wp->draw_text_node((*Gp)[v],string("%d",name[v]),node_color); }
  48.  
  49.  
  50.  
  51. static void draw_edge(edge e)
  52. { if (directed) 
  53.      Wp->draw_edge_arrow((*Gp)[source(e)],(*Gp)[target(e)],edge_color);
  54.   else 
  55.      Wp->draw_edge((*Gp)[source(e)],(*Gp)[target(e)],edge_color); 
  56.  }
  57.  
  58. static void message(string s)
  59. { s += "                              ";
  60.   Wp->del_message();
  61.   Wp->message(s);
  62. }
  63.  
  64.  
  65. static void read_graph(string s, bool clear = false)
  66. {
  67.   if (s=="") 
  68.   { message("No file.");
  69.     return;
  70.    }
  71.  
  72.   message(string("Reading file %s.",~s));
  73.  
  74.   GRAPH(point,int) X;
  75.   node v;
  76.   edge e;
  77.  
  78.   int x = X.read(s);
  79.  
  80.   if (x == 1) 
  81.   { message(string("Cannot open file %s.",~s));
  82.     return;
  83.    }
  84.  
  85.   if (x == 2)
  86.   { message("File is not written by graph_edit (random embedding).");
  87.     int max = grid_size-3;
  88.     int min = 2;
  89.     forall_nodes(v,X)
  90.       X[v] = point(random(min,max), random(min,max));
  91.    }
  92.  
  93.   if (clear) { Gp->clear(); Wp->clear(); }
  94.  
  95.   node_array(node) corr(X);
  96.  
  97.   forall_nodes(v,X) 
  98.   { node u = Gp->new_node(X[v]);
  99.     corr[v] = u;
  100.     name[u] = node_count++;
  101.     V[X[v]] = u;
  102.     draw_node(u);
  103.    }
  104.  
  105.   forall_edges(e,X) 
  106.   { Gp->new_edge(corr[source(e)],corr[target(e)]);
  107.     draw_edge(e);
  108.    }
  109. }
  110.  
  111.  
  112. static void save_graph(string s)
  113. { if (s=="") 
  114.   { message("Cannot open file.");
  115.     return;
  116.    }
  117.   message(string("writing to file %s",~s));
  118.   Gp->write(s);
  119.  }
  120.  
  121.  
  122. static void window_init()
  123.   Wp->init(0,grid_size,0,1);
  124.  
  125.   node v;
  126.   forall_nodes(v,*Gp) draw_node(v);
  127.  
  128.   edge e;
  129.   forall_edges(e,*Gp) draw_edge(e);
  130.  
  131. }
  132.  
  133.  
  134.  
  135. void graph_edit(window& W, GRAPH(point,int)& G, bool dir, bool redraw)
  136. {
  137.   real  x,y;
  138.   point p,q;
  139.   int   key;
  140.  
  141.   Wp = &W;
  142.   Gp = &G;
  143.  
  144.   directed = dir;
  145.  
  146.  
  147.   panel help_panel("GRAPH EDIT OPERATIONS");
  148.  
  149.   help_panel.text_item("                                                   ");
  150.   help_panel.text_item(" button                        (Shift)      (Ctrl) ");
  151.   help_panel.text_item("                                                   ");
  152.   help_panel.text_item(" LEFT   :  Insert/Move node  Delete node   Refresh ");
  153.   help_panel.text_item(" MIDDLE :  Insert edge       Delete edge   Settings");
  154.   help_panel.text_item(" RIGHT  :  Quit              File I/O      Help  ");
  155.   help_panel.text_item("                                                   ");
  156.   help_panel.button("continue");
  157.  
  158.  
  159.   panel init_panel("SETTINGS");
  160.  
  161.   init_panel.int_item("grid size",grid_size);
  162. //init_panel.int_item("node width",node_width,5,20);
  163. //init_panel.int_item("edge width",edge_width,1,8);
  164.   init_panel.color_item("node color",node_color);
  165.   init_panel.color_item("edge color",edge_color);
  166.   init_panel.button("continue");
  167.  
  168.   panel file_panel("FILE PANEL");
  169.  
  170.   string filename;
  171.  
  172.   file_panel.string_item("file name",filename);
  173.   file_panel.button("read");
  174.   file_panel.button("save"); 
  175.   file_panel.button("load");
  176.   file_panel.button("cancel"); 
  177.  
  178.   if (redraw) window_init();
  179.  
  180.   W.message(" GRAPH EDIT  ( help: <ctrl> + right button ) "); 
  181.  
  182.   drawing_mode save = W.set_mode(xor_mode);
  183.  
  184.   bool done = false;
  185.  
  186.   while ( ! done )
  187.   {
  188.      key = W.read_mouse(x,y);
  189.  
  190.      W.del_message();
  191.  
  192.      p = point(x,y);
  193.  
  194.      switch(key) {
  195.  
  196.      case 1:  { 
  197.                 node v;
  198.  
  199.                 if (V[p] == nil)        // new node
  200.                 { v  = G.new_node(p);
  201.                   name[v] = node_count++;
  202.                   draw_node(v);
  203.                   V[p] = v;
  204.                  }
  205.                 else                    // move node
  206.                 { v = V[p];
  207.  
  208.                   draw_node(v);
  209.  
  210.                   W.read_mouse_action(draw_node_cursor,x,y);
  211.  
  212.                   point q(x,y);           // new position
  213.  
  214.                   if (V[q] != nil)        // position not free
  215.                   { draw_node(v);
  216.                     break;
  217.                    }
  218.  
  219.                   V[p] = nil;
  220.  
  221.                   edge e;
  222.  
  223.                   forall_edges(e,G) 
  224.                     if (source(e) == v || target(e) == v) draw_edge(e);
  225.  
  226.                   G[v] = q;
  227.                   V[q] = v;
  228.                   draw_node(v);
  229.  
  230.                   forall_edges(e,G) 
  231.                     if (source(e) == v || target(e) == v) draw_edge(e);
  232.  
  233.                  }
  234.                 break;
  235.                }
  236.  
  237.  
  238.      case 2:  { // new edge
  239.                 int k;
  240.                 node v = V[p];
  241.                 node w;
  242.  
  243.                 if (v != nil)            
  244.                 { W.draw_filled_node(p);
  245.                   do 
  246.                   { k = W.read_mouse_seg(p.xcoord(),p.ycoord(),x,y);
  247.                     point q(x,y);
  248.                     w = V[q];
  249.                     if (w == nil) 
  250.                     { w  = G.new_node(q);    // new node
  251.                       name[w] = node_count++;
  252.                       draw_node(w);
  253.                       V[q] = w;
  254.                      }
  255.  
  256.                     draw_edge(G.new_edge(v,w));
  257.  
  258.                    } while ( w == nil && k == 2);
  259.   
  260.                   W.draw_filled_node(p);
  261.                  }
  262.  
  263.                 break;
  264.                }
  265.  
  266.  
  267.  
  268.      case  3: // return
  269.               W.set_mode(save);
  270.               done = true;
  271.               break;
  272.  
  273.  
  274.  
  275.      // Shift + mouse key
  276.  
  277.  
  278.      case -1: { // delete node
  279.  
  280.                 node v = V[p];
  281.  
  282.                 edge e;
  283.                 if (v != nil) 
  284.                 { forall_edges(e,G) 
  285.                     if (source(e) == v || target(e) == v) draw_edge(e);
  286.  
  287.                   draw_node(v);
  288.  
  289.                   G.del_node(v);
  290.                   V[p] = nil;
  291.                  }
  292.  
  293.                 }
  294.  
  295.      case -2: { // delete edge
  296.  
  297.                 node v = V[p];
  298.  
  299.                 if (v != nil) 
  300.                 { W.read_mouse_seg(p.xcoord(),p.ycoord(),x,y);
  301.                   q = point(x,y);
  302.                   node w = V[q];
  303.                   if (w != nil)
  304.                   { //linear search
  305.                     edge e = G.first_adj_edge(v);
  306.                     while (e != nil && target(e) != w) e = G.adj_succ(e);
  307.                     if (e != nil)
  308.                     { draw_edge(e);
  309.                       G.del_edge(e);
  310.                      }
  311.                    }
  312.                  }
  313.                 break;
  314.                }
  315.  
  316.  
  317.      case  -3: { // file menu 
  318.  
  319.                 switch(file_panel.open()) {
  320.  
  321.                    case 0 : // read
  322.                             read_graph(filename,false);
  323.                             break;
  324.   
  325.                    case 1 : // save
  326.                             save_graph(filename);
  327.                             break;
  328.  
  329.                    case 2 : // load 
  330.                             read_graph(filename,true);
  331.                             break;
  332.   
  333.                  }
  334.  
  335.                 break;
  336.               }
  337.  
  338.  
  339.  
  340.      // ctrl + mouse key
  341.  
  342.  
  343.      case 4:  // redraw 
  344.               window_init();
  345.               break;
  346.  
  347.      case 5:  // settings
  348.               init_panel.open();
  349.               window_init();
  350.               break;
  351.  
  352.      case 6:  // help
  353.               help_panel.open();
  354.               break;
  355.  
  356.  
  357.     } // switch
  358.  
  359.   } // for(;;)
  360.  
  361.   W.set_mode(save);
  362.  
  363. }
  364.