graph_displayer_canvas.cc
branchgui
changeset 27 e2c86ae158cf
parent 26 b0c76a4d5801
child 28 fa28f1071bd6
equal deleted inserted replaced
16:ecf5cfad4645 17:b783ad863af2
    89   writer.writeNodeMap("id", id);
    89   writer.writeNodeMap("id", id);
    90   writer.writeNodeMap("coordinates_x", xc);
    90   writer.writeNodeMap("coordinates_x", xc);
    91   writer.writeNodeMap("coordinates_y", yc);
    91   writer.writeNodeMap("coordinates_y", yc);
    92   writer.run();
    92   writer.run();
    93 }
    93 }
    94 
       
    95 int GraphDisplayerCanvas::changeLineWidth (std::string mapname)
       
    96 {
       
    97   for (EdgeIt i(g); i!=INVALID; ++i)
       
    98     {
       
    99       int w=(int)(*(mapstorage.edgemap_storage)[mapname])[i];
       
   100       if(w>=0)
       
   101 	{
       
   102 	  edgesmap[i]->property_width_pixels().set_value(w);
       
   103 	}
       
   104     }
       
   105   return 0;
       
   106 };
       
   107 
       
   108 int GraphDisplayerCanvas::changeColor (std::string mapname)
       
   109 {  
       
   110 
       
   111   //function maps the range of the maximum and
       
   112   //the minimum of the nodemap to the range of
       
   113   //green in RGB
       
   114 
       
   115   for (EdgeIt i(g); i!=INVALID; ++i)
       
   116   {
       
   117     double w=(*(mapstorage.edgemap_storage)[mapname])[i];
       
   118     double max=mapstorage.maxOfEdgeMap(mapname);
       
   119     double min=mapstorage.minOfEdgeMap(mapname);
       
   120       
       
   121     //std::cout<<w<<" "<<max<<" "<<min<<" "<<100*(w-min)/(max-min)<<std::endl;
       
   122     Gdk::Color color;
       
   123     if(max!=min)
       
   124     {
       
   125       color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
       
   126     }
       
   127     else
       
   128     {
       
   129       color.set_rgb_p (0, 100, 0);
       
   130     }
       
   131 
       
   132     edgesmap[i]->property_fill_color_gdk().set_value(color);
       
   133   }
       
   134   return 0;
       
   135 };
       
   136 
       
   137 int GraphDisplayerCanvas::changeText (std::string mapname)
       
   138 {
       
   139 
       
   140   //the number in the map will be written on the edge
       
   141   //EXCEPT when the name of the map is Text, because
       
   142   //in that case empty string will be written, because
       
   143   //that is the deleter map
       
   144   //\todo isn't it a bit woodcutter?
       
   145 
       
   146   for (EdgeIt i(g); i!=INVALID; ++i)
       
   147     {
       
   148       if(mapname!="Text")
       
   149 	{
       
   150 	  double number=(*(mapstorage.edgemap_storage)[mapname])[i];
       
   151 	  int length=1;
       
   152 	  //if number is smaller than one, length would be negative, or invalid
       
   153 	  if(number>=1)
       
   154 	    {
       
   155 	      length=(int)(floor(log(number)/log(10)))+1;
       
   156 	    }
       
   157 	  int maxpos=(int)(pow(10,length-1));
       
   158 	  int strl=length+1+RANGE;
       
   159 	  char * str=new char[strl];
       
   160 	  str[length]='.';
       
   161 	  str[strl]='\0';
       
   162       
       
   163 	  for(int j=0;j<strl;j++)
       
   164 	    {
       
   165 	      if(j!=length)
       
   166 		{
       
   167 		  int digit=(int)(number/maxpos);
       
   168 		  str[j]=(digit+'0');
       
   169 		  number-=digit*maxpos;
       
   170 		  number*=10;
       
   171 		}
       
   172 	    }
       
   173       
       
   174 	  edgetextmap[i]->property_text().set_value(str);
       
   175 	}
       
   176       else
       
   177 	{
       
   178 	  edgetextmap[i]->property_text().set_value("");
       
   179 	}
       
   180     }
       
   181   return 0;
       
   182 };
       
   183 
       
   184 //Deprecated
       
   185 bool GraphDisplayerCanvas::event_handler(GdkEvent* e, Node n)
       
   186 {
       
   187   switch(e->type)
       
   188   {
       
   189     case GDK_BUTTON_PRESS:
       
   190       //we mark the location of the event to be able to calculate parameters of dragging
       
   191       clicked_x=e->button.x;
       
   192       clicked_y=e->button.y;
       
   193       active_item=(get_item_at(e->button.x, e->button.y));
       
   194       isbutton=1;
       
   195       break;
       
   196     case GDK_BUTTON_RELEASE:
       
   197       isbutton=0;
       
   198       active_item=NULL;
       
   199       updateScrollRegion();
       
   200       break;
       
   201     case GDK_MOTION_NOTIFY:
       
   202       //we only have to do sg. if the mouse button is pressed
       
   203       if(isbutton)
       
   204       {
       
   205 	//new coordinates will be the old values,
       
   206 	//because the item will be moved to the
       
   207 	//new coordinate therefore the new movement
       
   208 	//has to be calculated from here
       
   209 
       
   210         double dx=e->motion.x-clicked_x;
       
   211         double dy=e->motion.y-clicked_y;
       
   212         active_item->move(dx, dy);
       
   213         clicked_x=e->motion.x;
       
   214         clicked_y=e->motion.y;
       
   215 
       
   216 	//all the edges connected to the moved point has to be redrawn
       
   217 
       
   218         EdgeIt e;
       
   219         g.firstOut(e,n);
       
   220         for(;e!=INVALID;g.nextOut(e))
       
   221         {
       
   222             Gnome::Canvas::Points coos;
       
   223             double x1, x2, y1, y2;
       
   224 
       
   225             nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
       
   226             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   227 
       
   228             nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
       
   229             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   230 
       
   231             edgesmap[e]->property_points().set_value(coos);
       
   232 
       
   233 	    edgesmap[e]->get_bounds(x1, y1, x2, y2);
       
   234 
       
   235 	    edgetextmap[e]->property_x().set_value((x1+x2)/2);
       
   236 	    edgetextmap[e]->property_y().set_value((y1+y2)/2);
       
   237         }
       
   238 
       
   239         g.firstIn(e,n);
       
   240         for(;e!=INVALID;g.nextIn(e))
       
   241         {
       
   242             Gnome::Canvas::Points coos;
       
   243             double x1, x2, y1, y2;
       
   244 
       
   245             nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
       
   246             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   247 
       
   248             nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
       
   249             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   250 
       
   251             edgesmap[e]->property_points().set_value(coos);
       
   252 
       
   253 	    edgesmap[e]->get_bounds(x1, y1, x2, y2);
       
   254 
       
   255 	    edgetextmap[e]->property_x().set_value((x1+x2)/2);
       
   256 	    edgetextmap[e]->property_y().set_value((y1+y2)/2);
       
   257         }
       
   258       }
       
   259     default: break;
       
   260   }
       
   261   return true;
       
   262 }
       
   263 
       
   264 bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
       
   265 {
       
   266   Gnome::Canvas::CanvasAA::on_expose_event(event);
       
   267   //usleep(10000);
       
   268   //rezoom();
       
   269   return true;
       
   270 }
       
   271 
       
   272 void GraphDisplayerCanvas::zoomIn()
       
   273 {
       
   274   set_pixels_per_unit(
       
   275       (1.0 + (double) zoom_step / 100.0) * get_pixels_per_unit());
       
   276 }
       
   277 
       
   278 void GraphDisplayerCanvas::zoomOut()
       
   279 {
       
   280   set_pixels_per_unit(
       
   281       (1.0 - (double) zoom_step / 100.0) * get_pixels_per_unit());
       
   282 }
       
   283 
       
   284 void GraphDisplayerCanvas::zoomFit()
       
   285 {
       
   286   // get the height and width of the canvas
       
   287   Gtk::Allocation a = get_allocation();
       
   288   int aw = a.get_width();
       
   289   int ah = a.get_height();
       
   290   // add some space
       
   291   aw -= 5; if (aw < 0) aw = 0;
       
   292   ah -= 5; if (ah < 0) ah = 0;
       
   293 
       
   294   // get the bounding box of the graph
       
   295   double wx1, wy1, wx2, wy2;
       
   296   Gnome::Canvas::Item* pCanvasItem = root();
       
   297   pCanvasItem->get_bounds(wx1, wy1, wx2, wy2);
       
   298 
       
   299   // fit the graph to the window
       
   300   double ppu1 = (double) aw / fabs(wx2 - wx1);
       
   301   double ppu2 = (double) ah / fabs(wy2 - wy1);
       
   302   set_pixels_per_unit((ppu1 < ppu2) ? ppu1 : ppu2);
       
   303 }
       
   304 
       
   305 void GraphDisplayerCanvas::zoom100()
       
   306 {
       
   307   set_pixels_per_unit(1.0);
       
   308 }
       
   309 
       
   310 void GraphDisplayerCanvas::updateScrollRegion()
       
   311 {
       
   312   double wx1, wy1, wx2, wy2;
       
   313   Gnome::Canvas::Item* pCanvasItem = root();
       
   314   pCanvasItem->get_bounds(wx1, wy1, wx2, wy2);
       
   315   set_scroll_region(wx1, wy1, wx2, wy2);
       
   316 }
       
   317 
       
   318 void GraphDisplayerCanvas::changeEditorialTool(int newtool)
       
   319 {
       
   320   actual_handler.disconnect();
       
   321 
       
   322   if(actual_tool==CREATE_EDGE)
       
   323     {
       
   324 	GdkEvent * generated=new GdkEvent();
       
   325 	generated->type=GDK_BUTTON_RELEASE;
       
   326 	generated->button.button=3;
       
   327 	create_edge_event_handler(generated);      
       
   328     }
       
   329 
       
   330   actual_tool=newtool;
       
   331 
       
   332   switch(newtool)
       
   333     {
       
   334     case MOVE:
       
   335       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::move_event_handler), false);
       
   336       break;
       
   337 
       
   338       //it has to assigned to canvas, because all the canvas has to be monitored, not only the elements of the already drawn group
       
   339     case CREATE_NODE:
       
   340       actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_node_event_handler), false);
       
   341       break;
       
   342 
       
   343     case CREATE_EDGE:
       
   344       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false);
       
   345       break;
       
   346 
       
   347     case ERASER:
       
   348       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraser_event_handler), false);
       
   349       break;
       
   350 
       
   351     default:
       
   352       break;
       
   353     }
       
   354 }
       
   355 
       
   356 int GraphDisplayerCanvas::get_actual_tool()
       
   357 {
       
   358   return actual_tool;
       
   359 }
       
   360 
       
   361 bool GraphDisplayerCanvas::move_event_handler(GdkEvent* e)
       
   362 {
       
   363   switch(e->type)
       
   364   {
       
   365     case GDK_BUTTON_PRESS:
       
   366       //we mark the location of the event to be able to calculate parameters of dragging
       
   367       clicked_x=e->button.x;
       
   368       clicked_y=e->button.y;
       
   369       active_item=(get_item_at(e->button.x, e->button.y));
       
   370       active_node=INVALID;
       
   371       for (NodeIt i(g); i!=INVALID; ++i)
       
   372 	{
       
   373 	  if(nodesmap[i]==active_item)
       
   374 	    {
       
   375 	      active_node=i;
       
   376 	    }
       
   377 	}
       
   378       switch(e->button.button)
       
   379 	{
       
   380 	case 3:      
       
   381 	  isbutton=3;
       
   382 	  break;
       
   383 	default:
       
   384 	  isbutton=1;
       
   385 	  break;
       
   386 	}
       
   387       break;
       
   388     case GDK_BUTTON_RELEASE:
       
   389       isbutton=0;
       
   390       active_item=NULL;
       
   391       active_node=INVALID;
       
   392       updateScrollRegion();
       
   393       break;
       
   394     case GDK_MOTION_NOTIFY:
       
   395       //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
       
   396       if(active_node!=INVALID)
       
   397       {
       
   398 	//new coordinates will be the old values,
       
   399 	//because the item will be moved to the
       
   400 	//new coordinate therefore the new movement
       
   401 	//has to be calculated from here
       
   402 
       
   403         double dx=e->motion.x-clicked_x;
       
   404         double dy=e->motion.y-clicked_y;
       
   405 
       
   406         active_item->move(dx, dy);
       
   407 
       
   408         clicked_x=e->motion.x;
       
   409         clicked_y=e->motion.y;
       
   410 
       
   411 	//all the edges connected to the moved point has to be redrawn
       
   412         EdgeIt ei;
       
   413 
       
   414         g.firstOut(ei,active_node);
       
   415 
       
   416         for(;ei!=INVALID;g.nextOut(ei))
       
   417         {
       
   418             Gnome::Canvas::Points coos;
       
   419             double x1, x2, y1, y2;
       
   420 
       
   421             nodesmap[g.source(ei)]->get_bounds(x1, y1, x2, y2);
       
   422             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   423 
       
   424             nodesmap[g.target(ei)]->get_bounds(x1, y1, x2, y2);
       
   425             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   426 
       
   427 	    if(isbutton==3)
       
   428 	      {
       
   429 		edgesmap[ei]->set_points(coos);
       
   430 	      }
       
   431 	    else
       
   432 	      {
       
   433 		edgesmap[ei]->set_points(coos,true);
       
   434 	      }
       
   435 
       
   436 	    xy<double> text_pos=edgesmap[ei]->get_arrow_pos();
       
   437 	    text_pos+=(xy<double>(10,10));
       
   438 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
       
   439 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
       
   440         }
       
   441 
       
   442         g.firstIn(ei,active_node);
       
   443         for(;ei!=INVALID;g.nextIn(ei))
       
   444         {
       
   445             Gnome::Canvas::Points coos;
       
   446             double x1, x2, y1, y2;
       
   447 
       
   448             nodesmap[g.source(ei)]->get_bounds(x1, y1, x2, y2);
       
   449             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   450 
       
   451             nodesmap[g.target(ei)]->get_bounds(x1, y1, x2, y2);
       
   452             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   453 
       
   454 	    if(isbutton==3)
       
   455 	      {
       
   456 		edgesmap[ei]->set_points(coos);
       
   457 	      }
       
   458 	    else
       
   459 	      {
       
   460 		edgesmap[ei]->set_points(coos,true);
       
   461 	      }
       
   462 
       
   463 	    xy<double> text_pos=edgesmap[ei]->get_arrow_pos();
       
   464 	    text_pos+=(xy<double>(10,10));
       
   465 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
       
   466 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
       
   467         }
       
   468       }
       
   469     default: break;
       
   470   }
       
   471 
       
   472   return true;
       
   473 }
       
   474 
       
   475 bool GraphDisplayerCanvas::create_node_event_handler(GdkEvent* e)
       
   476 {
       
   477   switch(e->type)
       
   478     {
       
   479 
       
   480       //draw the new node in red at the clicked place
       
   481     case GDK_BUTTON_PRESS:
       
   482       isbutton=1;
       
   483 
       
   484       active_node=NodeIt(g,g.addNode());
       
   485 
       
   486       //initiating values corresponding to new node in maps
       
   487       
       
   488 
       
   489       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
       
   490 
       
   491       nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph, clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
       
   492       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
       
   493       *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
       
   494       *(nodesmap[active_node]) << Gnome::Canvas::Properties::outline_color("black");
       
   495       (nodesmap[active_node])->show();
       
   496       break;
       
   497 
       
   498       //move the new node
       
   499     case GDK_MOTION_NOTIFY:
       
   500       {
       
   501 	double world_motion_x, world_motion_y;
       
   502 	GdkEvent * generated=new GdkEvent();
       
   503 	window_to_world (e->motion.x, e->motion.y, world_motion_x, world_motion_y);
       
   504 	generated->motion.x=world_motion_x;
       
   505 	generated->motion.y=world_motion_y;
       
   506 	generated->type=GDK_MOTION_NOTIFY;
       
   507 	move_event_handler(generated);      
       
   508 	break;
       
   509       }
       
   510 
       
   511       //finalize the new node
       
   512     case GDK_BUTTON_RELEASE:
       
   513       isbutton=0;
       
   514       *active_item << Gnome::Canvas::Properties::fill_color("blue");
       
   515       active_item=NULL;
       
   516       active_node=INVALID;
       
   517       updateScrollRegion();
       
   518       break;
       
   519     default:
       
   520       break;
       
   521     }
       
   522   return false;
       
   523 }
       
   524 
       
   525 bool GraphDisplayerCanvas::create_edge_event_handler(GdkEvent* e)
       
   526 {
       
   527   switch(e->type)
       
   528     {
       
   529     case GDK_BUTTON_PRESS:
       
   530       //in edge creation right button has special meaning
       
   531       if(e->button.button!=3)
       
   532 	{
       
   533 	  //there is not yet selected node
       
   534 	  if(active_node==INVALID)
       
   535 	    {
       
   536 	      //we mark the location of the event to be able to calculate parameters of dragging
       
   537 	      clicked_x=e->button.x;
       
   538 	      clicked_y=e->button.y;
       
   539 	      active_item=(get_item_at(e->button.x, e->button.y));
       
   540 	      active_node=INVALID;
       
   541 	      for (NodeIt i(g); i!=INVALID; ++i)
       
   542 		{
       
   543 		  if(nodesmap[i]==active_item)
       
   544 		    {
       
   545 		      active_node=i;
       
   546 		    }
       
   547 		}
       
   548 	      //the clicked item is really a node
       
   549 	      if(active_node!=INVALID)
       
   550 		{
       
   551 		  *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
       
   552 		  isbutton=1;
       
   553 		}
       
   554 	      //clicked item was not a node. It could be e.g. edge.
       
   555 	      else
       
   556 		{
       
   557 		  active_item=NULL;
       
   558 		}
       
   559 	    }
       
   560 	  //we only have to do sg. if the mouse button
       
   561 	  // is pressed already once AND the click was
       
   562 	  // on a node that was found in the set of 
       
   563 	  //nodes, and now we only search for the second 
       
   564 	  //node
       
   565 	  else
       
   566 	    {
       
   567 	      target_item=(get_item_at(e->button.x, e->button.y));
       
   568 	      Graph::NodeIt target_node=INVALID;
       
   569 	      for (NodeIt i(g); i!=INVALID; ++i)
       
   570 		{
       
   571 		  if(nodesmap[i]==target_item)
       
   572 		    {
       
   573 		      target_node=i;
       
   574 		    }
       
   575 		}
       
   576 	      //the clicked item is a node, the edge can be drawn
       
   577 	      if(target_node!=INVALID)
       
   578 		{
       
   579 		  *(nodesmap[target_node]) << Gnome::Canvas::Properties::fill_color("red");
       
   580 
       
   581 		  //creating new edge
       
   582 		  active_edge=EdgeIt(g,g.addEdge(active_node, target_node));
       
   583 
       
   584 		  //initiating values corresponding to new edge in maps
       
   585 		  mapstorage.init_maps_for_edge(active_edge);
       
   586 	  
       
   587 		  //calculating coordinates of new edge
       
   588 		  Gnome::Canvas::Points coos;
       
   589 		  double x1, x2, y1, y2;
       
   590 	  
       
   591 		  active_item->get_bounds(x1, y1, x2, y2);
       
   592 		  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   593 
       
   594 		  target_item->get_bounds(x1, y1, x2, y2);
       
   595 		  coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   596 
       
   597 		  //drawing new edge
       
   598 		  edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos, *this);
       
   599 		  *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green");
       
   600 		  edgesmap[active_edge]->property_width_pixels().set_value(10);
       
   601 
       
   602 		  //redraw nodes to blank terminations of the new edge
       
   603 		  target_item->raise_to_top();
       
   604 		  active_item->raise_to_top();
       
   605 
       
   606 		  //initializing edge-text as well, to empty string
       
   607 		  xy<double> text_pos=edgesmap[active_edge]->get_arrow_pos();
       
   608 		  text_pos+=(xy<double>(10,10));
       
   609 
       
   610 		  edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, "");
       
   611 		  edgetextmap[active_edge]->property_fill_color().set_value("black");
       
   612 		}
       
   613 	      //clicked item was not a node. it could be an e.g. edge. we do not deal with it furthermore.
       
   614 	      else
       
   615 		{
       
   616 		  target_item=NULL;
       
   617 		}
       
   618 	    }
       
   619 	}
       
   620       break;
       
   621     case GDK_BUTTON_RELEASE:
       
   622       isbutton=0;
       
   623       //we clear settings in two cases
       
   624       //1: the edge is ready (target_item has valid value)
       
   625       //2: the edge creation is cancelled with right button
       
   626       if((target_item)||(e->button.button==3))
       
   627 	{
       
   628 	  if(active_item)
       
   629 	    {
       
   630 	      *active_item << Gnome::Canvas::Properties::fill_color("blue");
       
   631 	      active_item=NULL;
       
   632 	    }
       
   633 	  if(target_item)
       
   634 	    {
       
   635 	      *target_item << Gnome::Canvas::Properties::fill_color("blue");
       
   636 	      target_item=NULL;
       
   637 	    }
       
   638 	  active_node=INVALID;
       
   639 	  active_edge=INVALID;
       
   640 	}
       
   641       break;
       
   642     default:
       
   643       break;
       
   644     }
       
   645   return false;
       
   646 }
       
   647 
       
   648 bool GraphDisplayerCanvas::eraser_event_handler(GdkEvent* e)
       
   649 {
       
   650   switch(e->type)
       
   651     {
       
   652     case GDK_BUTTON_PRESS:
       
   653       active_item=(get_item_at(e->button.x, e->button.y));
       
   654       active_node=INVALID;
       
   655       active_edge=INVALID;
       
   656       for (NodeIt i(g); i!=INVALID; ++i)
       
   657 	{
       
   658 	  if(nodesmap[i]==active_item)
       
   659 	    {
       
   660 	      active_node=i;
       
   661 	    }
       
   662 	}
       
   663       if(active_node==INVALID)
       
   664 	{
       
   665 	  for (EdgeIt i(g); i!=INVALID; ++i)
       
   666 	    {
       
   667 	      if(edgesmap[i]==active_item)
       
   668 		{
       
   669 		  active_edge=i;
       
   670 		}
       
   671 	    }
       
   672 	}
       
   673     *active_item << Gnome::Canvas::Properties::fill_color("red");
       
   674       break;
       
   675 
       
   676     case GDK_BUTTON_RELEASE:
       
   677       if(active_item==(get_item_at(e->button.x, e->button.y)))
       
   678 	{
       
   679 	  if(active_node!=INVALID)
       
   680 	    {
       
   681 
       
   682 	      //collecting edges to delete
       
   683 	      EdgeIt e;
       
   684 	      std::set<Graph::Edge> edges_to_delete;
       
   685 
       
   686 	      g.firstOut(e,active_node);
       
   687 	      for(;e!=INVALID;g.nextOut(e))
       
   688 		{
       
   689 		      edges_to_delete.insert(e);
       
   690 		}
       
   691 
       
   692 	      g.firstIn(e,active_node);
       
   693 	      for(;e!=INVALID;g.nextIn(e))
       
   694 		{
       
   695 		      edges_to_delete.insert(e);
       
   696 		}
       
   697 
       
   698 	      //deleting collected edges
       
   699 	      for(std::set<Graph::Edge>::iterator edge_set_it=edges_to_delete.begin();edge_set_it!=edges_to_delete.end();edge_set_it++)
       
   700 		{
       
   701 		  delete_item(*edge_set_it);
       
   702 		}
       
   703 	      delete_item(active_node);
       
   704 	    }
       
   705 	  //a simple edge was chosen
       
   706 	  else
       
   707 	    {
       
   708 	      delete_item(active_edge);
       
   709 	    }
       
   710 
       
   711 	  
       
   712 	}
       
   713       //pointer was moved, deletion is cancelled
       
   714       else
       
   715 	{
       
   716 	  if(active_node!=INVALID)
       
   717 	    {
       
   718 	      *active_item << Gnome::Canvas::Properties::fill_color("blue");
       
   719 	    }
       
   720 	  else
       
   721 	    {
       
   722 	      *active_item << Gnome::Canvas::Properties::fill_color("green");
       
   723 	    }
       
   724 	}
       
   725       //reseting datas
       
   726       active_item=NULL;
       
   727       active_edge=INVALID;
       
   728       active_node=INVALID;
       
   729       break;
       
   730 
       
   731     case GDK_MOTION_NOTIFY:
       
   732       break;
       
   733 
       
   734     default:
       
   735       break;
       
   736     }
       
   737   return true;
       
   738 }
       
   739 
       
   740 void GraphDisplayerCanvas::delete_item(NodeIt node_to_delete)
       
   741 {
       
   742   delete(nodesmap[node_to_delete]);
       
   743   g.erase(node_to_delete);
       
   744 }
       
   745 
       
   746 void GraphDisplayerCanvas::delete_item(EdgeIt edge_to_delete)
       
   747 {
       
   748   delete(edgesmap[edge_to_delete]);
       
   749   g.erase(edge_to_delete);
       
   750 }
       
   751 
       
   752 void GraphDisplayerCanvas::delete_item(Graph::Edge edge_to_delete)
       
   753 {
       
   754   delete(edgesmap[edge_to_delete]);
       
   755   g.erase(edge_to_delete);
       
   756 }
       
   757 
       
   758 void GraphDisplayerCanvas::text_reposition(xy<double> new_place)
       
   759 {
       
   760   new_place+=(xy<double>(10,10));
       
   761   edgetextmap[active_edge]->property_x().set_value(new_place.x);
       
   762   edgetextmap[active_edge]->property_y().set_value(new_place.y);
       
   763 }
       
   764 
       
   765 void GraphDisplayerCanvas::toggle_edge_activity(BrokenEdge* active_bre, bool on)
       
   766 {
       
   767   if(on)
       
   768     {
       
   769       if(active_edge!=INVALID)
       
   770 	{
       
   771 	  std::cout << "ERROR!!!! Valid edge found!" << std::endl;
       
   772 	}
       
   773       else
       
   774 	{
       
   775 	  for (EdgeIt i(g); i!=INVALID; ++i)
       
   776 	    {
       
   777 	      if(edgesmap[i]==active_bre)
       
   778 		{
       
   779 		  active_edge=i;
       
   780 		}
       
   781 	    }
       
   782 	}
       
   783     }
       
   784   else
       
   785     {
       
   786       if(active_edge!=INVALID)
       
   787 	{
       
   788 	  active_edge=INVALID;
       
   789 	}
       
   790       else
       
   791 	{
       
   792 	  std::cout << "ERROR!!!! Invalid edge found!" << std::endl;
       
   793 	}
       
   794     }
       
   795 
       
   796 }