graph_displayer_canvas-event.cc
author ladanyi
Fri, 26 Aug 2005 07:35:23 +0000
branchgui
changeset 66 4ca5a537ef07
parent 65 1b8e20c04704
child 69 6bb290b67e19
permissions -rwxr-xr-x
- use Gtk::Dialog to set the new values of edge and node maps
- update all edges/nodes when editing a map so that edge widths and node
sizes change properly
- coordinate maps are no longer selectable in the maps window
     1 #include "graph_displayer_canvas.h"
     2 #include "broken_edge.h"
     3 #include <cmath>
     4 
     5 
     6 bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
     7 {
     8   Gnome::Canvas::CanvasAA::on_expose_event(event);
     9   //usleep(10000);
    10   //rezoom();
    11   return true;
    12 }
    13 
    14 void GraphDisplayerCanvas::changeEditorialTool(int newtool)
    15 {
    16   if(actual_tool!=newtool)
    17     {
    18 
    19       actual_handler.disconnect();
    20 
    21       switch(actual_tool)
    22 	{
    23 	case CREATE_EDGE:
    24 	  {
    25 	    GdkEvent * generated=new GdkEvent();
    26 	    generated->type=GDK_BUTTON_RELEASE;
    27 	    generated->button.button=3;
    28 	    createEdgeEventHandler(generated);      
    29 	    break;
    30 	  }
    31 	case EDGE_MAP_EDIT:
    32 	  //has to do the same thing as in the case of NODE_MAP_EDIT
    33 	case NODE_MAP_EDIT:
    34 	  {
    35 	    break;
    36 	  }
    37 	default:
    38 	  break;
    39 	}
    40 
    41       active_item=NULL; 
    42       target_item=NULL; 
    43       active_edge=INVALID;	
    44       active_node=INVALID;	
    45 
    46 
    47       actual_tool=newtool;
    48   
    49       switch(newtool)
    50 	{
    51 	case MOVE:
    52 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
    53 	  break;
    54 
    55 	case CREATE_NODE:
    56 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
    57 	  break;
    58 
    59 	case CREATE_EDGE:
    60 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
    61 	  break;
    62 
    63 	case ERASER:
    64 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
    65 	  break;
    66 
    67 	case EDGE_MAP_EDIT:
    68 	  grab_focus();
    69 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::edgeMapEditEventHandler), false);
    70 	  break;
    71 
    72 	case NODE_MAP_EDIT:
    73 	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::nodeMapEditEventHandler), false);
    74 	  break;
    75 
    76 	default:
    77 	  break;
    78 	}
    79     }
    80 }
    81 
    82 int GraphDisplayerCanvas::getActualTool()
    83 {
    84   return actual_tool;
    85 }
    86 
    87 bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e)
    88 {
    89   switch(e->type)
    90   {
    91     case GDK_BUTTON_PRESS:
    92       //we mark the location of the event to be able to calculate parameters of dragging
    93       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
    94 
    95       active_item=(get_item_at(clicked_x, clicked_y));
    96       active_node=INVALID;
    97       for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
    98 	{
    99 	  if(nodesmap[i]==active_item)
   100 	    {
   101 	      active_node=i;
   102 	    }
   103 	}
   104       switch(e->button.button)
   105 	{
   106 	case 3:      
   107 	  isbutton=3;
   108 	  break;
   109 	default:
   110 	  isbutton=1;
   111 	  break;
   112 	}
   113       break;
   114     case GDK_BUTTON_RELEASE:
   115       isbutton=0;
   116       active_item=NULL;
   117       active_node=INVALID;
   118       break;
   119     case GDK_MOTION_NOTIFY:
   120       //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
   121       if(active_node!=INVALID)
   122       {
   123         mapstorage.modified = true;
   124         mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
   125 	//new coordinates will be the old values,
   126 	//because the item will be moved to the
   127 	//new coordinate therefore the new movement
   128 	//has to be calculated from here
   129 
   130 	double new_x, new_y;
   131 
   132 	window_to_world (e->motion.x, e->motion.y, new_x, new_y);
   133 
   134         double dx=new_x-clicked_x;
   135         double dy=new_y-clicked_y;
   136 
   137 	//repositioning node and its text
   138         active_item->move(dx, dy);
   139 	nodetextmap[active_node]->move(dx, dy);
   140 
   141         clicked_x=new_x;
   142         clicked_y=new_y;
   143 
   144 	//all the edges connected to the moved point has to be redrawn
   145         EdgeIt ei;
   146 
   147         mapstorage.graph.firstOut(ei,active_node);
   148 
   149         for(;ei!=INVALID;mapstorage.graph.nextOut(ei))
   150         {
   151             Gnome::Canvas::Points coos;
   152             double x1, x2, y1, y2;
   153 
   154             nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
   155             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   156 
   157             nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
   158             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   159 
   160 	    if(isbutton==3)
   161 	      {
   162 		edgesmap[ei]->setPoints(coos);
   163 	      }
   164 	    else
   165 	      {
   166 		edgesmap[ei]->setPoints(coos,true);
   167 	      }
   168 
   169 	    //reposition of edgetext
   170 	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
   171 	    text_pos+=(xy<double>(10,10));
   172 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
   173 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
   174         }
   175 
   176         mapstorage.graph.firstIn(ei,active_node);
   177         for(;ei!=INVALID;mapstorage.graph.nextIn(ei))
   178         {
   179             Gnome::Canvas::Points coos;
   180             double x1, x2, y1, y2;
   181 
   182             nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
   183             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   184 
   185             nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
   186             coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   187 
   188 	    if(isbutton==3)
   189 	      {
   190 		edgesmap[ei]->setPoints(coos);
   191 	      }
   192 	    else
   193 	      {
   194 		edgesmap[ei]->setPoints(coos,true);
   195 	      }
   196 
   197 	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
   198 	    text_pos+=(xy<double>(10,10));
   199 	    edgetextmap[ei]->property_x().set_value(text_pos.x);
   200 	    edgetextmap[ei]->property_y().set_value(text_pos.y);
   201         }
   202       }
   203     default: break;
   204   }
   205 
   206   return false;
   207 }
   208 
   209 bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
   210 {
   211   switch(e->type)
   212   {
   213     //move the new node
   214     case GDK_MOTION_NOTIFY:
   215       {
   216         GdkEvent * generated=new GdkEvent();
   217         generated->motion.x=e->motion.x;
   218         generated->motion.y=e->motion.y;
   219         generated->type=GDK_MOTION_NOTIFY;
   220         moveEventHandler(generated);      
   221         break;
   222       }
   223 
   224     case GDK_BUTTON_RELEASE:
   225       mapstorage.modified = true;
   226 
   227       isbutton=1;
   228 
   229       active_node=mapstorage.graph.addNode();
   230 
   231       //initiating values corresponding to new node in maps
   232 
   233       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   234 
   235       // update coordinates
   236       mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
   237 
   238       // update all other maps
   239       for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
   240           mapstorage.nodemap_storage.begin(); it !=
   241           mapstorage.nodemap_storage.end(); ++it)
   242       {
   243         if ((it->first != "coordinates_x") &&
   244             (it->first != "coordinates_y"))
   245         {
   246           (*(it->second))[active_node] =
   247             mapstorage.nodemap_default[it->first];
   248         }
   249       }
   250       // increment the id map's default value
   251       mapstorage.nodemap_default["id"] += 1.0;
   252 
   253       nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
   254           clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
   255       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
   256       *(nodesmap[active_node]) <<
   257         Gnome::Canvas::Properties::fill_color("blue");
   258       *(nodesmap[active_node]) <<
   259         Gnome::Canvas::Properties::outline_color("black");
   260       active_item->raise_to_top();
   261 
   262       (nodesmap[active_node])->show();
   263 
   264       nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph,
   265           clicked_x+node_property_defaults[N_RADIUS]+5,
   266           clicked_y+node_property_defaults[N_RADIUS]+5, "");
   267       nodetextmap[active_node]->property_fill_color().set_value("darkblue");
   268       nodetextmap[active_node]->raise_to_top();
   269 
   270       mapwin.updateNode(active_node);
   271 
   272       isbutton=0;
   273       target_item=NULL;
   274       active_item=NULL;
   275       active_node=INVALID;
   276 
   277       break;
   278     default:
   279       break;
   280   }
   281   return false;
   282 }
   283 
   284 bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
   285 {
   286   switch(e->type)
   287   {
   288     case GDK_BUTTON_PRESS:
   289       //in edge creation right button has special meaning
   290       if(e->button.button!=3)
   291       {
   292         //there is not yet selected node
   293         if(active_node==INVALID)
   294         {
   295           //we mark the location of the event to be able to calculate parameters of dragging
   296 
   297           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   298 
   299           active_item=(get_item_at(clicked_x, clicked_y));
   300           active_node=INVALID;
   301           for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   302           {
   303             if(nodesmap[i]==active_item)
   304             {
   305               active_node=i;
   306             }
   307           }
   308           //the clicked item is really a node
   309           if(active_node!=INVALID)
   310           {
   311             *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
   312             isbutton=1;
   313           }
   314           //clicked item was not a node. It could be e.g. edge.
   315           else
   316           {
   317             active_item=NULL;
   318           }
   319         }
   320         //we only have to do sg. if the mouse button
   321         // is pressed already once AND the click was
   322         // on a node that was found in the set of 
   323         //nodes, and now we only search for the second 
   324         //node
   325         else
   326         {
   327           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   328           target_item=(get_item_at(clicked_x, clicked_y));
   329           Node target_node=INVALID;
   330           for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   331           {
   332             if(nodesmap[i]==target_item)
   333             {
   334               target_node=i;
   335             }
   336           }
   337           //the clicked item is a node, the edge can be drawn
   338           if(target_node!=INVALID)
   339           {
   340             if(target_node!=active_node)		
   341             {
   342               mapstorage.modified = true;
   343 
   344               *(nodesmap[target_node]) <<
   345                 Gnome::Canvas::Properties::fill_color("red");
   346 
   347               //creating new edge
   348               active_edge=mapstorage.graph.addEdge(active_node,
   349                   target_node);
   350 
   351               // update maps
   352               for (std::map<std::string,
   353                   Graph::EdgeMap<double>*>::const_iterator it =
   354                   mapstorage.edgemap_storage.begin(); it !=
   355                   mapstorage.edgemap_storage.end(); ++it)
   356               {
   357                 (*(it->second))[active_edge] =
   358                   mapstorage.edgemap_default[it->first];
   359               }
   360               // increment the id map's default value
   361               mapstorage.edgemap_default["id"] += 1.0;
   362 
   363               //calculating coordinates of new edge
   364               Gnome::Canvas::Points coos;
   365               double x1, x2, y1, y2;
   366 
   367               active_item->get_bounds(x1, y1, x2, y2);
   368               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   369 
   370               target_item->get_bounds(x1, y1, x2, y2);
   371               coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   372 
   373               //drawing new edge
   374               edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos,
   375                   *this);
   376               *(edgesmap[active_edge]) <<
   377                 Gnome::Canvas::Properties::fill_color("green");
   378               edgesmap[active_edge]->property_width_pixels().set_value(10);
   379 
   380               edgesmap[active_edge]->lower_to_bottom();
   381 
   382               //initializing edge-text as well, to empty string
   383               xy<double> text_pos=edgesmap[active_edge]->getArrowPos();
   384               text_pos+=(xy<double>(10,10));
   385 
   386               edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
   387                   text_pos.x, text_pos.y, "");
   388               edgetextmap[active_edge]->property_fill_color().set_value(
   389                   "darkgreen");
   390               edgetextmap[active_edge]->raise_to_top();
   391 
   392               //updating its properties
   393               mapwin.updateEdge(active_edge);
   394             }
   395             else
   396             {
   397               target_node=INVALID;
   398               std::cerr << "Loop edge is not yet implemented!" << std::endl;
   399             }
   400           }
   401           //clicked item was not a node. it could be an e.g. edge. we do not
   402           //deal with it furthermore.
   403           else
   404           {
   405             target_item=NULL;
   406           }
   407         }
   408       }
   409       break;
   410     case GDK_BUTTON_RELEASE:
   411       isbutton=0;
   412       //we clear settings in two cases
   413       //1: the edge is ready (target_item has valid value)
   414       //2: the edge creation is cancelled with right button
   415       if((target_item)||(e->button.button==3))
   416       {
   417         if(active_item)
   418         {
   419           *active_item << Gnome::Canvas::Properties::fill_color("blue");
   420           active_item=NULL;
   421         }
   422         if(target_item)
   423         {
   424           *target_item << Gnome::Canvas::Properties::fill_color("blue");
   425           target_item=NULL;
   426         }
   427         active_node=INVALID;
   428         active_edge=INVALID;
   429       }
   430       break;
   431     default:
   432       break;
   433   }
   434   return false;
   435 }
   436 
   437 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
   438 {
   439   switch(e->type)
   440     {
   441     case GDK_BUTTON_PRESS:
   442       //finding the clicked items
   443       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   444       active_item=(get_item_at(clicked_x, clicked_y));
   445       active_node=INVALID;
   446       active_edge=INVALID;
   447       //was it a node?
   448       for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   449 	{
   450 	  if(nodesmap[i]==active_item)
   451 	    {
   452 	      active_node=i;
   453 	    }
   454 	}
   455       //or was it an edge?
   456       if(active_node==INVALID)
   457 	{
   458 	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   459 	    {
   460 	      if(edgesmap[i]==active_item)
   461 		{
   462 		  active_edge=i;
   463 		}
   464 	    }
   465 	}
   466 
   467       //recolor activated item
   468       if(active_item)
   469 	{
   470 	  *active_item << Gnome::Canvas::Properties::fill_color("red");
   471 	}
   472       break;
   473 
   474     case GDK_BUTTON_RELEASE:
   475       window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   476       if(active_item)
   477 	{
   478 	  //the cursor was not moved since pressing it
   479 	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
   480 	    {
   481 	      //a node was found
   482 	      if(active_node!=INVALID)
   483 		{
   484                   mapstorage.modified = true;
   485 
   486 		  //collecting edges to delete
   487 		  EdgeIt e;
   488 		  std::set<Graph::Edge> edges_to_delete;
   489 
   490 		  mapstorage.graph.firstOut(e,active_node);
   491 		  for(;e!=INVALID;mapstorage.graph.nextOut(e))
   492 		    {
   493 		      edges_to_delete.insert(e);
   494 		    }
   495 
   496 		  mapstorage.graph.firstIn(e,active_node);
   497 		  for(;e!=INVALID;mapstorage.graph.nextIn(e))
   498 		    {
   499 		      edges_to_delete.insert(e);
   500 		    }
   501 
   502 		  //deleting collected edges
   503 		  for(std::set<Graph::Edge>::iterator edge_set_it=edges_to_delete.begin();edge_set_it!=edges_to_delete.end();edge_set_it++)
   504 		    {
   505 		      deleteItem(*edge_set_it);
   506 		    }
   507 		  deleteItem(active_node);
   508 		}
   509 	      //a simple edge was chosen
   510 	      else
   511 		{
   512 		  deleteItem(active_edge);
   513 		}
   514 	    }
   515 	  //pointer was moved, deletion is cancelled
   516 	  else
   517 	    {
   518 	      if(active_node!=INVALID)
   519 		{
   520 		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
   521 		}
   522 	      else
   523 		{
   524 		  *active_item << Gnome::Canvas::Properties::fill_color("green");
   525 		}
   526 	    }
   527 	}
   528       //reseting datas
   529       active_item=NULL;
   530       active_edge=INVALID;
   531       active_node=INVALID;
   532       break;
   533 
   534     case GDK_MOTION_NOTIFY:
   535       break;
   536 
   537     default:
   538       break;
   539     }
   540   return false;
   541 }
   542 
   543 bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
   544 {
   545   if(actual_tool==EDGE_MAP_EDIT)
   546   {
   547     switch(e->type)
   548     {
   549       case GDK_BUTTON_PRESS:
   550         {
   551           //for determine, whether it was an edge
   552           Edge clicked_edge=INVALID;
   553 
   554           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   555           active_item=(get_item_at(clicked_x, clicked_y));
   556 
   557           //find the activated item between texts
   558           for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   559           {
   560             //at the same time only one can be active
   561             if(edgetextmap[i]==active_item)
   562             {
   563               clicked_edge=i;
   564             }
   565           }
   566 
   567           //if it was not between texts, search for it between edges
   568           if(clicked_edge==INVALID)
   569           {
   570             for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   571             {
   572               //at the same time only one can be active
   573               if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   574               {
   575                 clicked_edge=i;
   576               }
   577             }
   578           }
   579  
   580           //if it was really an edge...
   581           if(clicked_edge!=INVALID)
   582           {
   583             // the id map is not editable
   584             if (edgemap_to_edit == "id") return 0;
   585 
   586             //and there is activated map
   587             if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   588             {
   589               //activate the general variable for it
   590               active_edge=clicked_edge;
   591 
   592               //create a dialog
   593               Gtk::Dialog dialog("Edit value", *parentwin, true);
   594               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   595               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   596               Gtk::VBox* vbox = dialog.get_vbox();
   597               Gtk::Adjustment adj(
   598                   (*mapstorage.edgemap_storage[edgemap_to_edit])[active_edge],
   599                   -1000000.0,
   600                   1000000.0,
   601                   1.0, 5.0, 0.0);
   602               //TODO: find out why doesn't it work with
   603               //numeric_limits<double>::min/max
   604               Gtk::SpinButton spin(adj);
   605               spin.set_numeric(true);
   606               spin.set_digits(4);
   607               vbox->add(spin);
   608               spin.show();
   609               switch (dialog.run())
   610               {
   611                 case Gtk::RESPONSE_NONE:
   612                 case Gtk::RESPONSE_CANCEL:
   613                   break;
   614                 case Gtk::RESPONSE_ACCEPT:
   615                   double new_value = spin.get_value();
   616                   (*mapstorage.edgemap_storage[edgemap_to_edit])[active_edge] =
   617                     new_value;
   618                   std::ostringstream ostr;
   619                   ostr << new_value;
   620                   edgetextmap[active_edge]->property_text().set_value(
   621                       ostr.str());
   622                   //mapwin.updateEdge(active_edge);
   623                   mapwin.updateEdge(Edge(INVALID));
   624               }
   625             }
   626           }
   627           break;
   628         }
   629       default:
   630         break;
   631     }
   632   }
   633   return false;  
   634 }
   635 
   636 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   637 {
   638   if(actual_tool==NODE_MAP_EDIT)
   639   {
   640     switch(e->type)
   641     {
   642       case GDK_BUTTON_PRESS:
   643         {
   644           //for determine, whether it was a node
   645           Node clicked_node=INVALID;
   646 
   647           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   648           active_item=(get_item_at(clicked_x, clicked_y));
   649 
   650           //find the activated item between texts
   651           for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   652           {
   653             //at the same time only one can be active
   654             if(nodetextmap[i]==active_item)
   655             {
   656               clicked_node=i;
   657             }
   658           }
   659 
   660           //if there was not, search for it between nodes
   661           if(clicked_node==INVALID)
   662           {
   663             for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   664             {
   665               //at the same time only one can be active
   666               if(nodesmap[i]==active_item)
   667               {
   668                 clicked_node=i;
   669               }
   670             }
   671           }
   672 
   673           //if it was really a node...
   674           if(clicked_node!=INVALID)
   675           {
   676             // the id map is not editable
   677             if (nodemap_to_edit == "id") return 0;
   678 
   679             //and there is activated map
   680             if(nodetextmap[clicked_node]->property_text().get_value()!="")
   681             {
   682               //activate the general variable for it
   683               active_node=clicked_node;
   684 
   685               //create a dialog
   686               Gtk::Dialog dialog("Edit value", *parentwin, true);
   687               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   688               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   689               Gtk::VBox* vbox = dialog.get_vbox();
   690               Gtk::Adjustment adj(
   691                   (*mapstorage.nodemap_storage[nodemap_to_edit])[active_node],
   692                   -1000000.0,
   693                   1000000.0,
   694                   1.0, 5.0, 0.0);
   695               //TODO: find out why doesn't it work with
   696               //numeric_limits<double>::min/max
   697               Gtk::SpinButton spin(adj);
   698               spin.set_numeric(true);
   699               spin.set_digits(4);
   700               vbox->add(spin);
   701               spin.show();
   702               switch (dialog.run())
   703               {
   704                 case Gtk::RESPONSE_NONE:
   705                 case Gtk::RESPONSE_CANCEL:
   706                   break;
   707                 case Gtk::RESPONSE_ACCEPT:
   708                   double new_value = spin.get_value();
   709                   (*mapstorage.nodemap_storage[nodemap_to_edit])[active_node] =
   710                     new_value;
   711                   std::ostringstream ostr;
   712                   ostr << new_value;
   713                   nodetextmap[active_node]->property_text().set_value(
   714                       ostr.str());
   715                   //mapwin.updateNode(active_node);
   716                   mapwin.updateNode(Node(INVALID));
   717               }
   718             }
   719           }
   720           break;
   721         }
   722       default:
   723         break;
   724     }
   725   }
   726   return false;  
   727 }
   728 
   729 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   730 {
   731   delete(nodetextmap[node_to_delete]);
   732   delete(nodesmap[node_to_delete]);
   733   mapstorage.graph.erase(node_to_delete);
   734 }
   735 
   736 void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
   737 {
   738   delete(edgetextmap[edge_to_delete]);
   739   delete(edgesmap[edge_to_delete]);
   740   mapstorage.graph.erase(edge_to_delete);
   741 }
   742 
   743 void GraphDisplayerCanvas::textReposition(xy<double> new_place)
   744 {
   745   new_place+=(xy<double>(10,10));
   746   edgetextmap[forming_edge]->property_x().set_value(new_place.x);
   747   edgetextmap[forming_edge]->property_y().set_value(new_place.y);
   748 }
   749 
   750 void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
   751 {
   752   if(on)
   753     {
   754       if(forming_edge!=INVALID)
   755 	{
   756 	  std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
   757 	}
   758       else
   759 	{
   760 	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   761 	    {
   762 	      if(edgesmap[i]==active_bre)
   763 		{
   764 		  forming_edge=i;
   765 		}
   766 	    }
   767 	}
   768     }
   769   else
   770     {
   771       if(forming_edge!=INVALID)
   772 	{
   773 	  forming_edge=INVALID;
   774 	}
   775       else
   776 	{
   777 	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   778 	}
   779     }
   780 
   781 }
   782 
   783 int GraphDisplayerCanvas::addNewEdgeMap(double default_value, std::string mapname)
   784 {
   785   //create the new map
   786   Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mapstorage.graph, default_value);
   787 
   788   //if addition was not successful addEdgeMap returns one.
   789   //cause can be that there is already a map named like the new one
   790   if(mapstorage.addEdgeMap(mapname,emptr, default_value))
   791     {
   792       return 1;
   793     }
   794 
   795 
   796   //add it to the list of the displayable maps
   797   mapwin.registerNewEdgeMap(mapname);
   798 
   799   //display it
   800   changeEdgeText(mapname);
   801 
   802   return 0;
   803 }
   804 
   805 int GraphDisplayerCanvas::addNewNodeMap(double default_value, std::string mapname)
   806 {
   807   //create the new map
   808   Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mapstorage.graph,default_value);
   809 
   810   //if addition was not successful addNodeMap returns one.
   811   //cause can be that there is already a map named like the new one
   812   if(mapstorage.addNodeMap(mapname,emptr, default_value))
   813     {
   814       return 1;
   815     }
   816 
   817   //add it to the list of the displayable maps
   818   mapwin.registerNewNodeMap(mapname);
   819 
   820   //display it
   821   changeNodeText(mapname);
   822 
   823   return 0;
   824 }
   825