COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas-event.cc @ 151:72f1c33f89d4

Last change on this file since 151:72f1c33f89d4 was 151:72f1c33f89d4, checked in by Akos Ladanyi, 13 years ago

LoopEdge? improvements.

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