COIN-OR::LEMON - Graph Library

source: lemon-0.x/gui/graph_displayer_canvas-event.cc @ 1878:409a31271efd

Last change on this file since 1878:409a31271efd was 1860:27a9a75b957b, checked in by Akos Ladanyi, 14 years ago

Save and load the coordinates of the arrows on the edges.

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