gui/graph_displayer_canvas.cc
author deba
Wed, 15 Jun 2005 10:10:59 +0000
changeset 1492 0d58f0301923
parent 1485 3a1c6678fa23
child 1496 c60369a1c987
permissions -rwxr-xr-x
Correcting concept checks.
     1 #include <graph_displayer_canvas.h>
     2 #include <math.h>
     3 
     4 GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & gr, CoordinatesMap & cm, MapStorage & ms):g(gr),nodesmap(g),edgesmap(g),edgetextmap(g),displayed_graph(*(root()), 0, 0),mapstorage(ms),isbutton(false),active_item(NULL),target_item(NULL)
     5 {
     6   
     7   actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false);
     8 
     9   active_node=INVALID;
    10   active_edge=INVALID;
    11 
    12   //set_center_scroll_region(true);
    13 
    14   //first edges are drawn, to hide joining with nodes later
    15 
    16   for (EdgeIt i(g); i!=INVALID; ++i)
    17   {
    18 
    19     //drawing green lines, coordinates are from cm
    20 
    21     Gnome::Canvas::Points coos;
    22     coos.push_back(Gnome::Art::Point(cm[g.source(i)].x,cm[g.source(i)].y));
    23     coos.push_back(Gnome::Art::Point(cm[g.target(i)].x,cm[g.target(i)].y));
    24     
    25     edgesmap[i]=new Gnome::Canvas::Line(displayed_graph, coos);
    26     *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");
    27     edgesmap[i]->property_width_pixels().set_value(10);    
    28     
    29     //initializing edge-text as well, to empty string
    30 
    31     double x1, x2, y1, y2;
    32     edgesmap[i]->get_bounds(x1, y1, x2, y2);
    33     
    34     edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, "");
    35     edgetextmap[i]->property_fill_color().set_value("black");
    36   }
    37 
    38   //afterwards nodes come to be drawn
    39 
    40   NodeIt i(g);
    41   int maxx=0, maxy=0, minx=(int)cm[i].x, miny=(int)cm[i].y;
    42 
    43   for (; i!=INVALID; ++i)
    44   {
    45     //minimum and maximum is gathered to be able to zoom to the graph correctly (whole figure should be seen)
    46 
    47     if(cm[i].x>maxx)maxx=(int)cm[i].x;
    48     if(cm[i].y>maxy)maxy=(int)cm[i].y;
    49     if(cm[i].x<minx)minx=(int)cm[i].x;
    50     if(cm[i].y<miny)miny=(int)cm[i].y;
    51 
    52     //drawing bule nodes, with black line around them
    53 
    54     nodesmap[i]=new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
    55     *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
    56     *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
    57     //!!!!!!! (nodesmap[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),i));
    58   }
    59 
    60   updateScrollRegion();
    61 }
    62 
    63 GraphDisplayerCanvas::~GraphDisplayerCanvas()
    64 {
    65 
    66   //writing out the end state of the graph
    67   //\todo all the maps has to be write out!
    68 
    69   Graph::NodeMap <int> id(g);
    70   Graph::NodeMap <double> xc(g);
    71   Graph::NodeMap <double> yc(g);
    72   
    73   int j=1;
    74   
    75   for (NodeIt i(g); i!=INVALID; ++i)
    76   {
    77     double x1,y1,x2,y2;
    78     nodesmap[i]->get_bounds(x1, y1, x2, y2);
    79     
    80     id[i]=j++;
    81     xc[i]=(x1+x2)/2;
    82     yc[i]=(y1+y2)/2;
    83   }
    84 
    85   GraphWriter<Graph> writer(std::cout,g);
    86   
    87   writer.writeNodeMap("id", id);
    88   writer.writeNodeMap("coordinates_x", xc);
    89   writer.writeNodeMap("coordinates_y", yc);
    90   writer.run();
    91 }
    92 
    93 int GraphDisplayerCanvas::changeLineWidth (std::string mapname)
    94 {
    95   for (EdgeIt i(g); i!=INVALID; ++i)
    96   {
    97     int w=(int)(*(mapstorage.edgemap_storage)[mapname])[i];
    98     edgesmap[i]->property_width_pixels().set_value(w);
    99   }
   100   return 0;
   101 };
   102 
   103 int GraphDisplayerCanvas::changeColor (std::string mapname)
   104 {  
   105 
   106   //function maps the range of the maximum and
   107   //the minimum of the nodemap to the range of
   108   //green in RGB
   109 
   110   for (EdgeIt i(g); i!=INVALID; ++i)
   111   {
   112     double w=(*(mapstorage.edgemap_storage)[mapname])[i];
   113     double max=mapstorage.maxOfEdgeMap(mapname);
   114     double min=mapstorage.minOfEdgeMap(mapname);
   115       
   116     //std::cout<<w<<" "<<max<<" "<<min<<" "<<100*(w-min)/(max-min)<<std::endl;
   117     Gdk::Color color;
   118     if(max!=min)
   119     {
   120       color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
   121     }
   122     else
   123     {
   124       color.set_rgb_p (0, 100, 0);
   125     }
   126 
   127     edgesmap[i]->property_fill_color_gdk().set_value(color);
   128   }
   129   return 0;
   130 };
   131 
   132 int GraphDisplayerCanvas::changeText (std::string mapname)
   133 {
   134 
   135   //the number in the map will be written on the edge
   136   //EXCEPT when the name of the map is Text, because
   137   //in that case empty string will be written, because
   138   //that is the deleter map
   139   //\todo isn't it a bit woodcutter?
   140 
   141   for (EdgeIt i(g); i!=INVALID; ++i)
   142   {
   143     if(mapname!="Text")
   144     {
   145       double number=(*(mapstorage.edgemap_storage)[mapname])[i];
   146       int length=(int)(floor(log(number)/log(10)))+1;
   147       int maxpos=(int)(pow(10,length-1));
   148       int strl=length+1+RANGE;
   149       char * str=new char[strl];
   150       str[length]='.';
   151       str[strl]='\0';
   152       
   153       for(int j=0;j<strl;j++)
   154       {
   155 	if(j!=length)
   156         {
   157 	  int digit=(int)(number/maxpos);
   158 	  str[j]=(digit+'0');
   159 	  number-=digit*maxpos;
   160 	  number*=10;
   161         }
   162       }
   163       
   164       edgetextmap[i]->property_text().set_value(str);
   165     }
   166     else
   167     {
   168       edgetextmap[i]->property_text().set_value("");
   169     }
   170   }
   171   return 0;
   172 };
   173 
   174 bool GraphDisplayerCanvas::event_handler(GdkEvent* e, Node n)
   175 {
   176   switch(e->type)
   177   {
   178     case GDK_BUTTON_PRESS:
   179       //we mark the location of the event to be able to calculate parameters of dragging
   180       clicked_x=e->button.x;
   181       clicked_y=e->button.y;
   182       active_item=(get_item_at(e->button.x, e->button.y));
   183       isbutton=true;
   184       break;
   185     case GDK_BUTTON_RELEASE:
   186       isbutton=false;
   187       active_item=NULL;
   188       updateScrollRegion();
   189       break;
   190     case GDK_MOTION_NOTIFY:
   191       //we only have to do sg. if the mouse button is pressed
   192       if(isbutton)
   193       {
   194 	//new coordinates will be the old values,
   195 	//because the item will be moved to the
   196 	//new coordinate therefore the new movement
   197 	//has to be calculated from here
   198 
   199         double dx=e->motion.x-clicked_x;
   200         double dy=e->motion.y-clicked_y;
   201         active_item->move(dx, dy);
   202         clicked_x=e->motion.x;
   203         clicked_y=e->motion.y;
   204 
   205 	//all the edges connected to the moved point has to be redrawn
   206 
   207         EdgeIt e;
   208         g.firstOut(e,n);
   209         for(;e!=INVALID;g.nextOut(e))
   210         {
   211             Gnome::Canvas::Points coos;
   212             double x1, x2, y1, y2;
   213 
   214             nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
   215             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   216 
   217             nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
   218             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   219 
   220             edgesmap[e]->property_points().set_value(coos);
   221 
   222 	    edgesmap[e]->get_bounds(x1, y1, x2, y2);
   223 
   224 	    edgetextmap[e]->property_x().set_value((x1+x2)/2);
   225 	    edgetextmap[e]->property_y().set_value((y1+y2)/2);
   226         }
   227 
   228         g.firstIn(e,n);
   229         for(;e!=INVALID;g.nextIn(e))
   230         {
   231             Gnome::Canvas::Points coos;
   232             double x1, x2, y1, y2;
   233 
   234             nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
   235             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   236 
   237             nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
   238             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   239 
   240             edgesmap[e]->property_points().set_value(coos);
   241 
   242 	    edgesmap[e]->get_bounds(x1, y1, x2, y2);
   243 
   244 	    edgetextmap[e]->property_x().set_value((x1+x2)/2);
   245 	    edgetextmap[e]->property_y().set_value((y1+y2)/2);
   246         }
   247       }
   248     default: break;
   249   }
   250   return true;
   251 }
   252 
   253 bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
   254 {
   255   Gnome::Canvas::CanvasAA::on_expose_event(event);
   256   //usleep(10000);
   257   //rezoom();
   258   return true;
   259 }
   260 
   261 void GraphDisplayerCanvas::zoomIn()
   262 {
   263   set_pixels_per_unit(
   264       (1.0 + (double) zoom_step / 100.0) * get_pixels_per_unit());
   265 }
   266 
   267 void GraphDisplayerCanvas::zoomOut()
   268 {
   269   set_pixels_per_unit(
   270       (1.0 - (double) zoom_step / 100.0) * get_pixels_per_unit());
   271 }
   272 
   273 void GraphDisplayerCanvas::zoomFit()
   274 {
   275   // get the height and width of the canvas
   276   Gtk::Allocation a = get_allocation();
   277   int aw = a.get_width();
   278   int ah = a.get_height();
   279   // add some space
   280   aw -= 5; if (aw < 0) aw = 0;
   281   ah -= 5; if (ah < 0) ah = 0;
   282 
   283   // get the bounding box of the graph
   284   double wx1, wy1, wx2, wy2;
   285   Gnome::Canvas::Item* pCanvasItem = root();
   286   pCanvasItem->get_bounds(wx1, wy1, wx2, wy2);
   287 
   288   // fit the graph to the window
   289   double ppu1 = (double) aw / fabs(wx2 - wx1);
   290   double ppu2 = (double) ah / fabs(wy2 - wy1);
   291   set_pixels_per_unit((ppu1 < ppu2) ? ppu1 : ppu2);
   292 }
   293 
   294 void GraphDisplayerCanvas::zoom100()
   295 {
   296   set_pixels_per_unit(1.0);
   297 }
   298 
   299 void GraphDisplayerCanvas::updateScrollRegion()
   300 {
   301   double wx1, wy1, wx2, wy2;
   302   Gnome::Canvas::Item* pCanvasItem = root();
   303   pCanvasItem->get_bounds(wx1, wy1, wx2, wy2);
   304   set_scroll_region(wx1, wy1, wx2, wy2);
   305 }
   306 
   307 void GraphDisplayerCanvas::changeEditorialTool(int newtool)
   308 {
   309   actual_handler.disconnect();
   310 
   311   switch(newtool)
   312     {
   313     case MOVE:
   314       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::move_event_handler), false);
   315       break;
   316 
   317       //it has to assigned to canvas, because all the canvas has to be monitored, not only the elements of the already drawn group
   318     case CREATE_NODE:
   319       actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_node_event_handler), false);
   320       break;
   321 
   322     case CREATE_EDGE:
   323       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false);
   324       break;
   325 
   326     case ERASER:
   327       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraser_event_handler), false);
   328       break;
   329 
   330     default:
   331       break;
   332     }
   333 }
   334 
   335 bool GraphDisplayerCanvas::move_event_handler(GdkEvent* e)
   336 {
   337   switch(e->type)
   338   {
   339     case GDK_BUTTON_PRESS:
   340       //we mark the location of the event to be able to calculate parameters of dragging
   341       clicked_x=e->button.x;
   342       clicked_y=e->button.y;
   343       active_item=(get_item_at(e->button.x, e->button.y));
   344       active_node=INVALID;
   345       for (NodeIt i(g); i!=INVALID; ++i)
   346 	{
   347 	  if(nodesmap[i]==active_item)
   348 	    {
   349 	      active_node=i;
   350 	    }
   351 	}
   352       isbutton=true;
   353       break;
   354     case GDK_BUTTON_RELEASE:
   355       isbutton=false;
   356       active_item=NULL;
   357       active_node=INVALID;
   358       updateScrollRegion();
   359       break;
   360     case GDK_MOTION_NOTIFY:
   361       //we only have to do sg. if the mouse button is pressed AND the click was on a node that was found in the set of nodes
   362       if(active_node!=INVALID)
   363       {
   364 	//new coordinates will be the old values,
   365 	//because the item will be moved to the
   366 	//new coordinate therefore the new movement
   367 	//has to be calculated from here
   368 
   369         double dx=e->motion.x-clicked_x;
   370         double dy=e->motion.y-clicked_y;
   371 
   372         active_item->move(dx, dy);
   373 
   374         clicked_x=e->motion.x;
   375         clicked_y=e->motion.y;
   376 
   377 	//all the edges connected to the moved point has to be redrawn
   378         EdgeIt e;
   379 
   380         g.firstOut(e,active_node);
   381 
   382         for(;e!=INVALID;g.nextOut(e))
   383         {
   384             Gnome::Canvas::Points coos;
   385             double x1, x2, y1, y2;
   386 
   387             nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
   388             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   389 
   390             nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
   391             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   392 
   393             edgesmap[e]->property_points().set_value(coos);
   394 
   395 	    edgesmap[e]->get_bounds(x1, y1, x2, y2);
   396 
   397 	    edgetextmap[e]->property_x().set_value((x1+x2)/2);
   398 	    edgetextmap[e]->property_y().set_value((y1+y2)/2);
   399         }
   400 
   401         g.firstIn(e,active_node);
   402         for(;e!=INVALID;g.nextIn(e))
   403         {
   404             Gnome::Canvas::Points coos;
   405             double x1, x2, y1, y2;
   406 
   407             nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
   408             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   409 
   410             nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
   411             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   412 
   413             edgesmap[e]->property_points().set_value(coos);
   414 
   415 	    edgesmap[e]->get_bounds(x1, y1, x2, y2);
   416 
   417 	    edgetextmap[e]->property_x().set_value((x1+x2)/2);
   418 	    edgetextmap[e]->property_y().set_value((y1+y2)/2);
   419         }
   420       }
   421     default: break;
   422   }
   423 
   424   return true;
   425 }
   426 
   427 bool GraphDisplayerCanvas::create_node_event_handler(GdkEvent* e)
   428 {
   429   switch(e->type)
   430     {
   431 
   432       //draw the new node in red at the clicked place
   433     case GDK_BUTTON_PRESS:
   434       isbutton=true;
   435 
   436       active_node=NodeIt(g,g.addNode());
   437 
   438       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   439 
   440       nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph, clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
   441       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
   442       *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
   443       *(nodesmap[active_node]) << Gnome::Canvas::Properties::outline_color("black");
   444       (nodesmap[active_node])->show();
   445       break;
   446 
   447       //move the new node
   448     case GDK_MOTION_NOTIFY:
   449       {
   450 	double world_motion_x, world_motion_y;
   451 	GdkEvent * generated=new GdkEvent();
   452 	window_to_world (e->motion.x, e->motion.y, world_motion_x, world_motion_y);
   453 	generated->motion.x=world_motion_x;
   454 	generated->motion.y=world_motion_y;
   455 	generated->type=GDK_MOTION_NOTIFY;
   456 	move_event_handler(generated);      
   457 	break;
   458       }
   459 
   460       //finalize the new node
   461     case GDK_BUTTON_RELEASE:
   462       isbutton=false;
   463       *active_item << Gnome::Canvas::Properties::fill_color("blue");
   464       active_item=NULL;
   465       active_node=INVALID;
   466       updateScrollRegion();
   467       break;
   468     default:
   469       break;
   470     }
   471   return false;
   472 }
   473 
   474 bool GraphDisplayerCanvas::create_edge_event_handler(GdkEvent* e)
   475 {
   476   switch(e->type)
   477     {
   478     case GDK_BUTTON_PRESS:
   479       //in edge creatino right button has special meaning
   480       if(e->button.button!=3)
   481 	{
   482 	  //there is not yet selected node
   483 	  if(active_node==INVALID)
   484 	    {
   485 	      //we mark the location of the event to be able to calculate parameters of dragging
   486 	      clicked_x=e->button.x;
   487 	      clicked_y=e->button.y;
   488 	      active_item=(get_item_at(e->button.x, e->button.y));
   489 	      active_node=INVALID;
   490 	      for (NodeIt i(g); i!=INVALID; ++i)
   491 		{
   492 		  if(nodesmap[i]==active_item)
   493 		    {
   494 		      active_node=i;
   495 		    }
   496 		}
   497 	      //the clicked item is really a node
   498 	      if(active_node!=INVALID)
   499 		{
   500 		  *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
   501 		  isbutton=true;
   502 		}
   503 	      //clicked item was not a node. It could be e.g. edge.
   504 	      else
   505 		{
   506 		  active_item=NULL;
   507 		}
   508 	    }
   509 	  //we only have to do sg. if the mouse button
   510 	  // is pressed already once AND the click was
   511 	  // on a node that was found in the set of 
   512 	  //nodes, and now we only search for the second 
   513 	  //node
   514 	  else
   515 	    {
   516 	      target_item=(get_item_at(e->button.x, e->button.y));
   517 	      Graph::NodeIt target_node=INVALID;
   518 	      for (NodeIt i(g); i!=INVALID; ++i)
   519 		{
   520 		  if(nodesmap[i]==target_item)
   521 		    {
   522 		      target_node=i;
   523 		    }
   524 		}
   525 	      //the clicked item is a node, the edge can be drawn
   526 	      if(target_node!=INVALID)
   527 		{
   528 		  *(nodesmap[target_node]) << Gnome::Canvas::Properties::fill_color("red");
   529 
   530 		  //creating new edge
   531 		  active_edge=EdgeIt(g,g.addEdge(active_node, target_node));
   532 	  
   533 		  //calculating coordinates of new edge
   534 		  Gnome::Canvas::Points coos;
   535 		  double x1, x2, y1, y2;
   536 	  
   537 		  active_item->get_bounds(x1, y1, x2, y2);
   538 		  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   539 
   540 		  target_item->get_bounds(x1, y1, x2, y2);
   541 		  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   542 
   543 		  //drawing new edge
   544 		  edgesmap[active_edge]=new Gnome::Canvas::Line(displayed_graph, coos);
   545 		  *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green");
   546 		  edgesmap[active_edge]->property_width_pixels().set_value(10);
   547 
   548 		  //redraw nodes to blank terminations of the new edge
   549 		  target_item->raise_to_top();
   550 		  active_item->raise_to_top();
   551 
   552 		  //initializing edge-text as well, to empty string
   553 		  edgesmap[active_edge]->get_bounds(x1, y1, x2, y2);
   554 		  edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, "");
   555 		  edgetextmap[active_edge]->property_fill_color().set_value("black");
   556 		}
   557 	      //clicked item was not a node. it could be an e.g. edge. we do not deal with it furthermore.
   558 	      else
   559 		{
   560 		  target_item=NULL;
   561 		}
   562 	    }
   563 	}
   564       break;
   565     case GDK_BUTTON_RELEASE:
   566       isbutton=false;
   567       //we clear settings in two cases
   568       //1: the edge is ready (target_item has valid value)
   569       //2: the edge creation is cancelled with right button
   570       if((target_item)||(e->button.button==3))
   571 	{
   572 	  if(active_item)
   573 	    {
   574 	      *active_item << Gnome::Canvas::Properties::fill_color("blue");
   575 	      active_item=NULL;
   576 	    }
   577 	  if(target_item)
   578 	    {
   579 	      *target_item << Gnome::Canvas::Properties::fill_color("blue");
   580 	      target_item=NULL;
   581 	    }
   582 	  active_node=INVALID;
   583 	  active_edge=INVALID;
   584 	}
   585       break;
   586     default:
   587       break;
   588     }
   589   return false;
   590 }
   591 
   592 bool GraphDisplayerCanvas::eraser_event_handler(GdkEvent* e)
   593 {
   594   switch(e->type)
   595     {
   596     case GDK_BUTTON_PRESS:
   597       active_item=(get_item_at(e->button.x, e->button.y));
   598       active_node=INVALID;
   599       active_edge=INVALID;
   600       for (NodeIt i(g); i!=INVALID; ++i)
   601 	{
   602 	  if(nodesmap[i]==active_item)
   603 	    {
   604 	      active_node=i;
   605 	    }
   606 	}
   607       if(active_node==INVALID)
   608 	{
   609 	  for (EdgeIt i(g); i!=INVALID; ++i)
   610 	    {
   611 	      if(edgesmap[i]==active_item)
   612 		{
   613 		  active_edge=i;
   614 		}
   615 	    }
   616 	}
   617     *active_item << Gnome::Canvas::Properties::fill_color("red");
   618       break;
   619 
   620     case GDK_BUTTON_RELEASE:
   621       if(active_item==(get_item_at(e->button.x, e->button.y)))
   622 	{
   623 	  if(active_node!=INVALID)
   624 	    {
   625 //	      EdgeIt e;
   626 // 	      g.firstOut(e,active_node);
   627 // 	      for(;e!=INVALID;g.nextOut(e))
   628 // 		{
   629 // 		  if(e!=INVALID)delete_item(e);
   630 // 		}
   631 
   632 // 	      g.firstIn(e,active_node);
   633 // 	      for(;e!=INVALID;g.nextIn(e))
   634 // 		{
   635 // 		  if(e!=INVALID)delete_item(e);
   636 // 		}
   637 	      for (EdgeIt i(g); i!=INVALID; ++i)
   638 		{
   639 		  //std::cout << g.source(i).id << "-" << g.target(i).id << " " << active_node.id << std::endl;
   640 		  if((g.source(i)==active_node)||(g.target(i)==active_node))
   641 		    {
   642 		      delete_item(i);
   643 		    }
   644 		}
   645 	      delete_item(active_node);
   646 	    }
   647 	  else
   648 	    {
   649 	      delete_item(active_edge);
   650 	    }
   651 
   652 	  
   653 	}
   654       else
   655 	{
   656 	  if(active_node!=INVALID)
   657 	    {
   658 	      *active_item << Gnome::Canvas::Properties::fill_color("blue");
   659 	    }
   660 	  else
   661 	    {
   662 	      *active_item << Gnome::Canvas::Properties::fill_color("green");
   663 	    }
   664 	}
   665       active_item=NULL;
   666       active_edge=INVALID;
   667       active_node=INVALID;
   668       break;
   669 
   670     case GDK_MOTION_NOTIFY:
   671       break;
   672 
   673     default:
   674       break;
   675     }
   676   return true;
   677 }
   678 
   679 void GraphDisplayerCanvas::delete_item(NodeIt node_to_delete)
   680 {
   681   delete(nodesmap[node_to_delete]);
   682   g.erase(node_to_delete);
   683 }
   684 
   685 void GraphDisplayerCanvas::delete_item(EdgeIt edge_to_delete)
   686 {
   687   delete(edgesmap[edge_to_delete]);
   688   g.erase(edge_to_delete);
   689 }
   690