⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _graph_edit.c

📁 数据类型和算法库LEDA 数据类型和算法库LEDA
💻 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 + -