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