COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas-event.cc @ 147:10ef59f6633c

Last change on this file since 147:10ef59f6633c was 147:10ef59f6633c, checked in by Akos Ladanyi, 14 years ago

Loop edges.

  • Property exe set to *
File size: 25.3 KB
Line 
1#include "graph_displayer_canvas.h"
2#include <cmath>
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{
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
81int GraphDisplayerCanvas::getActualTool()
82{
83  return actual_tool;
84}
85
86bool 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((mytab.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        (mytab.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 - (mytab.mapstorage).coords[active_node].x);
148        double coord_y = new_y - (clicked_y - (mytab.mapstorage).coords[active_node].y);
149
150        // write back the new coordinates to the coords map
151        (mytab.mapstorage).coords.set(active_node, xy<double>(coord_x, coord_y));
152
153        clicked_x=new_x;
154        clicked_y=new_y;
155
156        // reposition the coordinates text
157        std::ostringstream ostr;
158        ostr << "(" <<
159          (mytab.mapstorage).coords[active_node].x << ", " <<
160          (mytab.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((mytab.mapstorage).coords[active_node].x +
168              radius);
169          coord_text->property_y().set_value((mytab.mapstorage).coords[active_node].y -
170              radius);
171        }
172        else
173        {
174          coord_text = new Gnome::Canvas::Text(
175              displayed_graph,
176              (mytab.mapstorage).coords[active_node].x + radius,
177              (mytab.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((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
185        {
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]);
192
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);
198
199            mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
200            edgesmap[ei]->draw();
201
202            //reposition of edgetext
203            XY text_pos=mytab.mapstorage.arrow_pos[ei];
204            text_pos+=(XY(10,10));
205            edgetextmap[ei]->property_x().set_value(text_pos.x);
206            edgetextmap[ei]->property_y().set_value(text_pos.y);
207        }
208
209        for(InEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
210        {
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]);
217
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);
223
224            mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
225            edgesmap[ei]->draw();
226
227            //reposition of edgetext
228            XY text_pos=mytab.mapstorage.arrow_pos[ei];
229            text_pos+=(XY(10,10));
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
237  return false;
238}
239
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
292bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
293{
294  switch(e->type)
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      }
306
307    case GDK_BUTTON_RELEASE:
308      (mytab.mapstorage).modified = true;
309
310      isbutton=1;
311
312      active_node=(mytab.mapstorage).graph.addNode();
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
318      // update coordinates
319      (mytab.mapstorage).coords.set(active_node, xy<double>(clicked_x, clicked_y));
320
321      // update all other maps
322      for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
323          (mytab.mapstorage).nodemap_storage.begin(); it !=
324          (mytab.mapstorage).nodemap_storage.end(); ++it)
325      {
326        if ((it->first != "coordinates_x") &&
327            (it->first != "coordinates_y"))
328        {
329          (*(it->second))[active_node] =
330            (mytab.mapstorage).nodemap_default[it->first];
331        }
332      }
333      // increment the id map's default value
334      (mytab.mapstorage).nodemap_default["label"] += 1.0;
335
336      nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
337          clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
338      active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
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
345      (nodesmap[active_node])->show();
346
347      nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph,
348          clicked_x+node_property_defaults[N_RADIUS]+5,
349          clicked_y+node_property_defaults[N_RADIUS]+5, "");
350      nodetextmap[active_node]->property_fill_color().set_value("darkblue");
351      nodetextmap[active_node]->raise_to_top();
352
353//       mapwin.updateNode(active_node);
354      propertyUpdate(active_node);
355
356      isbutton=0;
357      target_item=NULL;
358      active_item=NULL;
359      active_node=INVALID;
360      break;
361    default:
362      break;
363  }
364  return false;
365}
366
367bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
368{
369  switch(e->type)
370  {
371    case GDK_BUTTON_PRESS:
372      //in edge creation right button has special meaning
373      if(e->button.button!=3)
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
379
380          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
381
382          active_item=(get_item_at(clicked_x, clicked_y));
383          active_node=INVALID;
384          for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
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;
413          for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
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            {
425              (mytab.mapstorage).modified = true;
426
427              *(nodesmap[target_node]) <<
428                Gnome::Canvas::Properties::fill_color("red");
429
430              //creating new edge
431              active_edge=(mytab.mapstorage).graph.addEdge(active_node,
432                  target_node);
433
434              // update maps
435              for (std::map<std::string,
436                  Graph::EdgeMap<double>*>::const_iterator it =
437                  (mytab.mapstorage).edgemap_storage.begin(); it !=
438                  (mytab.mapstorage).edgemap_storage.end(); ++it)
439              {
440                (*(it->second))[active_edge] =
441                  (mytab.mapstorage).edgemap_default[it->first];
442              }
443              // increment the id map's default value
444              (mytab.mapstorage).edgemap_default["label"] += 1.0;
445
446              //calculating coordinates of new edge
447              Gnome::Canvas::Points coos;
448              double x1, x2, y1, y2;
449
450              active_item->get_bounds(x1, y1, x2, y2);
451              coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
452
453              target_item->get_bounds(x1, y1, x2, y2);
454              coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
455
456              // set the coordinates of the arrow on the new edge
457              MapStorage& ms = mytab.mapstorage;
458              ms.arrow_pos.set(active_edge,
459                  (ms.coords[ms.graph.source(active_edge)] +
460                   ms.coords[ms.graph.target(active_edge)])/ 2.0);
461
462              //drawing new edge
463              edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge,
464                  *this);
465
466              //initializing edge-text as well, to empty string
467              XY text_pos=mytab.mapstorage.arrow_pos[active_edge];
468              text_pos+=(XY(10,10));
469
470              edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
471                  text_pos.x, text_pos.y, "");
472              edgetextmap[active_edge]->property_fill_color().set_value(
473                  "darkgreen");
474              edgetextmap[active_edge]->raise_to_top();
475
476              //updating its properties
477//               mapwin.updateEdge(active_edge);
478              propertyUpdate(active_edge);
479            }
480            else
481            {
482              target_node=INVALID;
483              std::cerr << "Loop edge is not yet implemented!" << std::endl;
484            }
485          }
486          //clicked item was not a node. it could be an e.g. edge. we do not
487          //deal with it furthermore.
488          else
489          {
490            target_item=NULL;
491          }
492        }
493      }
494      break;
495    case GDK_BUTTON_RELEASE:
496      isbutton=0;
497      //we clear settings in two cases
498      //1: the edge is ready (target_item has valid value)
499      //2: the edge creation is cancelled with right button
500      if((target_item)||(e->button.button==3))
501      {
502        if(active_item)
503        {
504          *active_item << Gnome::Canvas::Properties::fill_color("blue");
505          active_item=NULL;
506        }
507        if(target_item)
508        {
509          *target_item << Gnome::Canvas::Properties::fill_color("blue");
510          target_item=NULL;
511        }
512        active_node=INVALID;
513        active_edge=INVALID;
514      }
515      break;
516    default:
517      break;
518  }
519  return false;
520}
521
522bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
523{
524  switch(e->type)
525    {
526    case GDK_BUTTON_PRESS:
527      //finding the clicked items
528      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
529      active_item=(get_item_at(clicked_x, clicked_y));
530      active_node=INVALID;
531      active_edge=INVALID;
532      //was it a node?
533      for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
534        {
535          if(nodesmap[i]==active_item)
536            {
537              active_node=i;
538            }
539        }
540      //or was it an edge?
541      if(active_node==INVALID)
542        {
543          for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
544            {
545              if(edgesmap[i]==active_item)
546                {
547                  active_edge=i;
548                }
549            }
550        }
551
552      // return if the clicked object is neither an edge nor a node
553      if (active_edge == INVALID) return false;
554     
555      //recolor activated item
556      if(active_item)
557        {
558          *active_item << Gnome::Canvas::Properties::fill_color("red");
559        }
560      break;
561
562    case GDK_BUTTON_RELEASE:
563      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
564      if(active_item)
565        {
566          //the cursor was not moved since pressing it
567          if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
568            {
569              //a node was found
570              if(active_node!=INVALID)
571                {
572                  (mytab.mapstorage).modified = true;
573
574                  std::set<Graph::Edge> edges_to_delete;
575
576                  for(OutEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
577                    {
578                      edges_to_delete.insert(e);
579                    }
580                 
581                  for(InEdgeIt e((mytab.mapstorage).graph,active_node);e!=INVALID;++e)
582                    {
583                      edges_to_delete.insert(e);
584                    }
585                 
586                  //deleting collected edges
587                  for(std::set<Graph::Edge>::iterator
588                        edge_set_it=edges_to_delete.begin();
589                      edge_set_it!=edges_to_delete.end();
590                      ++edge_set_it)
591                    {
592                      deleteItem(*edge_set_it);
593                    }
594                  deleteItem(active_node);
595                }
596              //a simple edge was chosen
597              else if (active_edge != INVALID)
598                {
599                  deleteItem(active_edge);
600                }
601            }
602          //pointer was moved, deletion is cancelled
603          else
604            {
605              if(active_node!=INVALID)
606                {
607                  *active_item << Gnome::Canvas::Properties::fill_color("blue");
608                }
609              else if (active_edge != INVALID)
610                {
611                  *active_item << Gnome::Canvas::Properties::fill_color("green");
612                }
613            }
614        }
615      //reseting datas
616      active_item=NULL;
617      active_edge=INVALID;
618      active_node=INVALID;
619      break;
620
621    case GDK_MOTION_NOTIFY:
622      break;
623
624    default:
625      break;
626    }
627  return false;
628}
629
630bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
631{
632  if(actual_tool==EDGE_MAP_EDIT)
633  {
634    switch(e->type)
635    {
636      case GDK_BUTTON_PRESS:
637        {
638          //for determine, whether it was an edge
639          Edge clicked_edge=INVALID;
640
641          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
642          active_item=(get_item_at(clicked_x, clicked_y));
643
644          //find the activated item between texts
645          for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
646          {
647            //at the same time only one can be active
648            if(edgetextmap[i]==active_item)
649            {
650              clicked_edge=i;
651            }
652          }
653
654          //if it was not between texts, search for it between edges
655          if(clicked_edge==INVALID)
656          {
657            for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
658            {
659              //at the same time only one can be active
660              if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
661              {
662                clicked_edge=i;
663              }
664            }
665          }
666 
667          //if it was really an edge...
668          if(clicked_edge!=INVALID)
669          {
670            // the id map is not editable
671            if (edgemap_to_edit == "label") return 0;
672
673            //and there is activated map
674            if(edgetextmap[clicked_edge]->property_text().get_value()!="")
675            {
676              //activate the general variable for it
677              active_edge=clicked_edge;
678
679              //create a dialog
680              Gtk::Dialog dialog("Edit value", true);
681              dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
682              dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
683              Gtk::VBox* vbox = dialog.get_vbox();
684              Gtk::SpinButton spin(0.0, 4);
685              spin.set_increments(1.0, 10.0);
686              spin.set_range(-1000000.0, 1000000.0);
687              spin.set_numeric(true);
688              vbox->add(spin);
689              spin.show();
690              switch (dialog.run())
691              {
692                case Gtk::RESPONSE_NONE:
693                case Gtk::RESPONSE_CANCEL:
694                  break;
695                case Gtk::RESPONSE_ACCEPT:
696                  double new_value = spin.get_value();
697                  (*(mytab.mapstorage).edgemap_storage[edgemap_to_edit])[active_edge] =
698                    new_value;
699                  std::ostringstream ostr;
700                  ostr << new_value;
701                  edgetextmap[active_edge]->property_text().set_value(
702                      ostr.str());
703                  //mapwin.updateEdge(active_edge);
704//                   mapwin.updateEdge(Edge(INVALID));
705                  propertyUpdate(Edge(INVALID));
706              }
707            }
708          }
709          break;
710        }
711      default:
712        break;
713    }
714  }
715  return false; 
716}
717
718bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
719{
720  if(actual_tool==NODE_MAP_EDIT)
721  {
722    switch(e->type)
723    {
724      case GDK_BUTTON_PRESS:
725        {
726          //for determine, whether it was a node
727          Node clicked_node=INVALID;
728
729          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
730          active_item=(get_item_at(clicked_x, clicked_y));
731
732          //find the activated item between texts
733          for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
734          {
735            //at the same time only one can be active
736            if(nodetextmap[i]==active_item)
737            {
738              clicked_node=i;
739            }
740          }
741
742          //if there was not, search for it between nodes
743          if(clicked_node==INVALID)
744          {
745            for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
746            {
747              //at the same time only one can be active
748              if(nodesmap[i]==active_item)
749              {
750                clicked_node=i;
751              }
752            }
753          }
754
755          //if it was really a node...
756          if(clicked_node!=INVALID)
757          {
758            // the id map is not editable
759            if (nodemap_to_edit == "label") return 0;
760
761            //and there is activated map
762            if(nodetextmap[clicked_node]->property_text().get_value()!="")
763            {
764              //activate the general variable for it
765              active_node=clicked_node;
766
767              //create a dialog
768              Gtk::Dialog dialog("Edit value", true);
769              dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
770              dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
771              Gtk::VBox* vbox = dialog.get_vbox();
772              Gtk::SpinButton spin(0.0, 4);
773              spin.set_increments(1.0, 10.0);
774              spin.set_range(-1000000.0, 1000000.0);
775              spin.set_numeric(true);
776              vbox->add(spin);
777              spin.show();
778              switch (dialog.run())
779              {
780                case Gtk::RESPONSE_NONE:
781                case Gtk::RESPONSE_CANCEL:
782                  break;
783                case Gtk::RESPONSE_ACCEPT:
784                  double new_value = spin.get_value();
785                  (*(mytab.mapstorage).nodemap_storage[nodemap_to_edit])[active_node] =
786                    new_value;
787                  std::ostringstream ostr;
788                  ostr << new_value;
789                  nodetextmap[active_node]->property_text().set_value(
790                      ostr.str());
791                  //mapwin.updateNode(active_node);
792//                   mapwin.updateNode(Node(INVALID));
793                  propertyUpdate(Node(INVALID));
794              }
795            }
796          }
797          break;
798        }
799      default:
800        break;
801    }
802  }
803  return false; 
804}
805
806void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
807{
808  delete(nodetextmap[node_to_delete]);
809  delete(nodesmap[node_to_delete]);
810  (mytab.mapstorage).graph.erase(node_to_delete);
811}
812
813void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
814{
815  delete(edgetextmap[edge_to_delete]);
816  delete(edgesmap[edge_to_delete]);
817  (mytab.mapstorage).graph.erase(edge_to_delete);
818}
819
820void GraphDisplayerCanvas::textReposition(xy<double> new_place)
821{
822  new_place+=(xy<double>(10,10));
823  edgetextmap[forming_edge]->property_x().set_value(new_place.x);
824  edgetextmap[forming_edge]->property_y().set_value(new_place.y);
825}
826
827void GraphDisplayerCanvas::toggleEdgeActivity(EdgeBase* active_bre, bool on)
828{
829  if(on)
830  {
831    if(forming_edge!=INVALID)
832    {
833      std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
834    }
835    else
836    {
837      for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
838      {
839        if(edgesmap[i]==active_bre)
840        {
841          forming_edge=i;
842        }
843      }
844    }
845  }
846  else
847  {
848    if(forming_edge!=INVALID)
849    {
850      forming_edge=INVALID;
851    }
852    else
853    {
854      std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
855    }
856  }
857}
Note: See TracBrowser for help on using the repository browser.