📄 _graph_edit.c
字号:
/*******************************************************************************
+
+ LEDA 3.0
+
+
+ _graph_edit.c
+
+
+ Copyright (c) 1992 by Max-Planck-Institut fuer Informatik
+ Im Stadtwald, 6600 Saarbruecken, FRG
+ All rights reserved.
+
*******************************************************************************/
#include <LEDA/graph_edit.h>
static window* Wp;
static GRAPH<point,int>* Gp;
static color node_color = blue;
static color edge_color = red;
static bool directed;
static int x_min, x_max, y_min;
static double node_radius;
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",index(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);
//Wp->draw_left_arc_edge(segment((*Gp)[source(e)],(*Gp)[target(e)]),edge_color);
}
static void message(window& W, string s)
{ s += " ";
W.del_message();
W.message(s);
}
static edge find_edge(node v, node w)
{ edge e = Gp->first_adj_edge(v);
while (e != nil && target(e) != w) e = Gp->adj_succ(e);
return e;
}
static node V(GRAPH<point,int>& G, point p) // returns node at position p
{ node v;
forall_nodes(v,G)
if (p.distance(G[v]) < node_radius) return v;
return nil;
}
static void read_graph(window& W, GRAPH<point,int>& G,string s,bool clear=false)
{
if (s=="")
{ message(W,"No file.");
return;
}
message(W,string("Reading file %s.",~s));
GRAPH<point,int> X;
node v;
edge e;
int x = X.read(s);
if (x == 1)
{ message(W,string("Cannot open file %s.",~s));
return;
}
if (x == 2)
{ message(W,"File is not written by graph_edit (random embedding).");
int max = int(W.xmax())-3;
int min = 2;
forall_nodes(v,X)
X[v] = point(random(min,max), random(min,max));
}
if (clear) { G.clear(); W.clear(); }
node_array<node> corr(X);
forall_nodes(v,X)
{ node u = G.new_node(X[v]);
corr[v] = u;
draw_node(u);
}
forall_edges(e,X)
{ G.new_edge(corr[source(e)],corr[target(e)]);
draw_edge(e);
}
}
static void save_graph(window& W, GRAPH<point,int>& G,string s)
{ if (s=="")
{ message(W,"Cannot open file.");
return;
}
message(W,string("writing to file %s",~s));
G.write(s);
}
static void window_init(window& W, GRAPH<point,int>& G)
{
W.init(x_min,x_max,y_min,0);
node_radius = W.get_node_width()/W.scale();
node v;
forall_nodes(v,G) draw_node(v);
edge e;
forall_edges(e,G) draw_edge(e);
}
void graph_edit(window& W, GRAPH<point,int>& G, bool dir, bool redraw)
{
double x,y;
point p,q;
int key;
Wp = &W;
Gp = &G;
x_min = (int)W.xmin();
x_max = (int)W.xmax();
y_min = (int)W.ymin();
directed = dir;
node_radius = W.get_node_width()/W.scale();
panel help_panel("GRAPH EDIT OPERATIONS");
help_panel.text_item(" ");
help_panel.text_item(" LEFT MIDDLE RIGHT ");
help_panel.text_item(" ");
help_panel.text_item(" insert/move node insert edge exit ");
help_panel.text_item("(shift) delete node delete edge file ");
help_panel.text_item("(ctrl ) clear settings help ");
help_panel.text_item(" ");
help_panel.button("continue");
panel init_panel("SETTINGS");
init_panel.int_item("x_min",x_min);
init_panel.int_item("x_max",x_max);
init_panel.int_item("y_min",y_min);
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,G);
W.message("GRAPH EDIT");
W.message("(press <ctrl> right button for help) ");
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 = V(G,p);
if (v == nil) // new node
{ v = G.new_node(p);
draw_node(v);
}
else // move node
{
draw_node(v);
W.read_mouse_action(draw_node_cursor,x,y);
point q(x,y); // new position
if (V(G,q) != nil) // position not free
{ draw_node(v);
break;
}
edge e;
forall_edges(e,G)
if (source(e) == v || target(e) == v) draw_edge(e);
G[v] = q;
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(G,p);
node w;
if (v != nil)
{ p = G[v];
W.draw_filled_node(p);
do
{ k = W.read_mouse_seg(p.xcoord(),p.ycoord(),x,y);
point q(x,y);
w = V(G,q);
if (w == nil)
{ w = G.new_node(q); // new node
draw_node(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(G,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);
}
}
case -2: { // delete edge
node v = V(G,p);
if (v != nil)
{ p = G[v];
W.read_mouse_seg(p.xcoord(),p.ycoord(),x,y);
q = point(x,y);
node w = V(G,q);
if (w != nil)
{ edge e = find_edge(v,w);
if (e != nil)
{ draw_edge(e);
G.del_edge(e);
}
}
}
break;
}
case -3: { // file menu
switch(file_panel.open()) {
case 0 : // read
read_graph(W,G,filename,false);
break;
case 1 : // save
save_graph(W,G,filename);
break;
case 2 : // load
read_graph(W,G,filename,true);
break;
}
break;
}
// ctrl + mouse key
case 4: // clear
G.clear();
W.clear();
break;
case 5: // settings
init_panel.open();
window_init(W,G);
break;
case 6: // help
help_panel.open();
break;
} // switch
} // for(;;)
W.set_mode(save);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -