home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- +
- + LEDA 2.1.1 11-15-1991
- +
- +
- + _graph_edit.c
- +
- +
- + Copyright (c) 1991 by Max-Planck-Institut fuer Informatik
- + Im Stadtwald, 6600 Saarbruecken, FRG
- + All rights reserved.
- +
- *******************************************************************************/
-
-
- #include <LEDA/graph_edit.h>
- #include <LEDA/d_array.h>
-
- declare2(d_array,point,node)
- declare2(d_array,node,int)
-
- declare(node_array,node)
-
- static window* Wp;
- static GRAPH(point,int)* Gp;
-
- static int node_count = 0;
-
- static d_array(point,node) V(nil);
- static d_array(node,int) name;
-
-
- //static int node_width = 12;
- //static int edge_width = 1;
-
- static color node_color = blue;
- static color edge_color = red;
- static int grid_size = 50;
-
- static bool directed;
-
-
- static void draw_node_cursor(double x, double y)
- { Wp->draw_node(x,y); }
-
-
- static void draw_node(node v)
- { Wp->draw_text_node((*Gp)[v],string("%d",name[v]),node_color); }
-
-
-
- static void draw_edge(edge e)
- { if (directed)
- Wp->draw_edge_arrow((*Gp)[source(e)],(*Gp)[target(e)],edge_color);
- else
- Wp->draw_edge((*Gp)[source(e)],(*Gp)[target(e)],edge_color);
- }
-
- static void message(string s)
- { s += " ";
- Wp->del_message();
- Wp->message(s);
- }
-
-
- static void read_graph(string s, bool clear = false)
- {
- if (s=="")
- { message("No file.");
- return;
- }
-
- message(string("Reading file %s.",~s));
-
- GRAPH(point,int) X;
- node v;
- edge e;
-
- int x = X.read(s);
-
- if (x == 1)
- { message(string("Cannot open file %s.",~s));
- return;
- }
-
- if (x == 2)
- { message("File is not written by graph_edit (random embedding).");
- int max = grid_size-3;
- int min = 2;
- forall_nodes(v,X)
- X[v] = point(random(min,max), random(min,max));
- }
-
- if (clear) { Gp->clear(); Wp->clear(); }
-
- node_array(node) corr(X);
-
- forall_nodes(v,X)
- { node u = Gp->new_node(X[v]);
- corr[v] = u;
- name[u] = node_count++;
- V[X[v]] = u;
- draw_node(u);
- }
-
- forall_edges(e,X)
- { Gp->new_edge(corr[source(e)],corr[target(e)]);
- draw_edge(e);
- }
- }
-
-
- static void save_graph(string s)
- { if (s=="")
- { message("Cannot open file.");
- return;
- }
- message(string("writing to file %s",~s));
- Gp->write(s);
- }
-
-
- static void window_init()
- {
- Wp->init(0,grid_size,0,1);
-
- node v;
- forall_nodes(v,*Gp) draw_node(v);
-
- edge e;
- forall_edges(e,*Gp) draw_edge(e);
-
- }
-
-
-
- void graph_edit(window& W, GRAPH(point,int)& G, bool dir, bool redraw)
- {
- real x,y;
- point p,q;
- int key;
-
- Wp = &W;
- Gp = &G;
-
- directed = dir;
-
-
- panel help_panel("GRAPH EDIT OPERATIONS");
-
- help_panel.text_item(" ");
- help_panel.text_item(" button (Shift) (Ctrl) ");
- help_panel.text_item(" ");
- help_panel.text_item(" LEFT : Insert/Move node Delete node Refresh ");
- help_panel.text_item(" MIDDLE : Insert edge Delete edge Settings");
- help_panel.text_item(" RIGHT : Quit File I/O Help ");
- help_panel.text_item(" ");
- help_panel.button("continue");
-
-
- panel init_panel("SETTINGS");
-
- init_panel.int_item("grid size",grid_size);
- //init_panel.int_item("node width",node_width,5,20);
- //init_panel.int_item("edge width",edge_width,1,8);
- init_panel.color_item("node color",node_color);
- init_panel.color_item("edge color",edge_color);
- init_panel.button("continue");
-
- panel file_panel("FILE PANEL");
-
- string filename;
-
- file_panel.string_item("file name",filename);
- file_panel.button("read");
- file_panel.button("save");
- file_panel.button("load");
- file_panel.button("cancel");
-
- if (redraw) window_init();
-
- W.message(" GRAPH EDIT ( help: <ctrl> + right button ) ");
-
- drawing_mode save = W.set_mode(xor_mode);
-
- bool done = false;
-
- while ( ! done )
- {
- key = W.read_mouse(x,y);
-
- W.del_message();
-
- p = point(x,y);
-
- switch(key) {
-
- case 1: {
- node v;
-
- if (V[p] == nil) // new node
- { v = G.new_node(p);
- name[v] = node_count++;
- draw_node(v);
- V[p] = v;
- }
- else // move node
- { v = V[p];
-
- draw_node(v);
-
- W.read_mouse_action(draw_node_cursor,x,y);
-
- point q(x,y); // new position
-
- if (V[q] != nil) // position not free
- { draw_node(v);
- break;
- }
-
- V[p] = nil;
-
- edge e;
-
- forall_edges(e,G)
- if (source(e) == v || target(e) == v) draw_edge(e);
-
- G[v] = q;
- V[q] = v;
- draw_node(v);
-
- forall_edges(e,G)
- if (source(e) == v || target(e) == v) draw_edge(e);
-
- }
- break;
- }
-
-
- case 2: { // new edge
- int k;
- node v = V[p];
- node w;
-
- if (v != nil)
- { W.draw_filled_node(p);
- do
- { k = W.read_mouse_seg(p.xcoord(),p.ycoord(),x,y);
- point q(x,y);
- w = V[q];
- if (w == nil)
- { w = G.new_node(q); // new node
- name[w] = node_count++;
- draw_node(w);
- V[q] = w;
- }
-
- draw_edge(G.new_edge(v,w));
-
- } while ( w == nil && k == 2);
-
- W.draw_filled_node(p);
- }
-
- break;
- }
-
-
-
- case 3: // return
- W.set_mode(save);
- done = true;
- break;
-
-
-
- // Shift + mouse key
-
-
- case -1: { // delete node
-
- node v = V[p];
-
- edge e;
- if (v != nil)
- { forall_edges(e,G)
- if (source(e) == v || target(e) == v) draw_edge(e);
-
- draw_node(v);
-
- G.del_node(v);
- V[p] = nil;
- }
-
- }
-
- case -2: { // delete edge
-
- node v = V[p];
-
- if (v != nil)
- { W.read_mouse_seg(p.xcoord(),p.ycoord(),x,y);
- q = point(x,y);
- node w = V[q];
- if (w != nil)
- { //linear search
- edge e = G.first_adj_edge(v);
- while (e != nil && target(e) != w) e = G.adj_succ(e);
- if (e != nil)
- { draw_edge(e);
- G.del_edge(e);
- }
- }
- }
- break;
- }
-
-
- case -3: { // file menu
-
- switch(file_panel.open()) {
-
- case 0 : // read
- read_graph(filename,false);
- break;
-
- case 1 : // save
- save_graph(filename);
- break;
-
- case 2 : // load
- read_graph(filename,true);
- break;
-
- }
-
- break;
- }
-
-
-
- // ctrl + mouse key
-
-
- case 4: // redraw
- window_init();
- break;
-
- case 5: // settings
- init_panel.open();
- window_init();
- break;
-
- case 6: // help
- help_panel.open();
- break;
-
-
- } // switch
-
- } // for(;;)
-
- W.set_mode(save);
-
- }
-