COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas-event.cc @ 63:59768817442a

gui
Last change on this file since 63:59768817442a was 63:59768817442a, checked in by Akos Ladanyi, 15 years ago
  • id maps are not editable
  • handle exceptions thrown by the file reader
  • texts are always above the edges
  • store a default value for all maps, so that edges and nodes created after adding a new map receive the default value too
  • create node on button release, not on click (fixes a few oddities)
  • Property exe set to *
File size: 26.2 KB
Line 
1#include "graph_displayer_canvas.h"
2#include "broken_edge.h"
3#include <cmath>
4
5
6bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
7{
8  Gnome::Canvas::CanvasAA::on_expose_event(event);
9  //usleep(10000);
10  //rezoom();
11  return true;
12}
13
14void GraphDisplayerCanvas::changeEditorialTool(int newtool)
15{
16  if(actual_tool!=newtool)
17    {
18
19      actual_handler.disconnect();
20
21      switch(actual_tool)
22        {
23        case CREATE_EDGE:
24          {
25            GdkEvent * generated=new GdkEvent();
26            generated->type=GDK_BUTTON_RELEASE;
27            generated->button.button=3;
28            createEdgeEventHandler(generated);     
29            break;
30          }
31        case EDGE_MAP_EDIT:
32          //has to do the same thing as in the case of NODE_MAP_EDIT
33        case NODE_MAP_EDIT:
34          {
35            GdkEvent * generated=new GdkEvent();
36            generated->type=GDK_KEY_PRESS;
37            ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
38            entryWidgetChangeHandler(generated);
39            entrywidget.hide();
40            break;
41          }
42        default:
43          break;
44        }
45
46      active_item=NULL;
47      target_item=NULL;
48      active_edge=INVALID;     
49      active_node=INVALID;     
50
51
52      actual_tool=newtool;
53 
54      switch(newtool)
55        {
56        case MOVE:
57          actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
58          break;
59
60        case CREATE_NODE:
61          actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
62          break;
63
64        case CREATE_EDGE:
65          actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
66          break;
67
68        case ERASER:
69          actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
70          break;
71
72        case EDGE_MAP_EDIT:
73          grab_focus();
74          actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::edgeMapEditEventHandler), false);
75          break;
76
77        case NODE_MAP_EDIT:
78          actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::nodeMapEditEventHandler), false);
79          break;
80
81        default:
82          break;
83        }
84    }
85}
86
87int GraphDisplayerCanvas::getActualTool()
88{
89  return actual_tool;
90}
91
92bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e)
93{
94  switch(e->type)
95  {
96    case GDK_BUTTON_PRESS:
97      //we mark the location of the event to be able to calculate parameters of dragging
98      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
99
100      active_item=(get_item_at(clicked_x, clicked_y));
101      active_node=INVALID;
102      for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
103        {
104          if(nodesmap[i]==active_item)
105            {
106              active_node=i;
107            }
108        }
109      switch(e->button.button)
110        {
111        case 3:     
112          isbutton=3;
113          break;
114        default:
115          isbutton=1;
116          break;
117        }
118      break;
119    case GDK_BUTTON_RELEASE:
120      isbutton=0;
121      active_item=NULL;
122      active_node=INVALID;
123      break;
124    case GDK_MOTION_NOTIFY:
125      //we only have to do sg. if the mouse button is pressed AND the click was on a node that was found in the set of nodes
126      if(active_node!=INVALID)
127      {
128        mapstorage.modified = true;
129        mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
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        clicked_x=new_x;
147        clicked_y=new_y;
148
149        //all the edges connected to the moved point has to be redrawn
150        EdgeIt ei;
151
152        mapstorage.graph.firstOut(ei,active_node);
153
154        for(;ei!=INVALID;mapstorage.graph.nextOut(ei))
155        {
156            Gnome::Canvas::Points coos;
157            double x1, x2, y1, y2;
158
159            nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
160            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
161
162            nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
163            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
164
165            if(isbutton==3)
166              {
167                edgesmap[ei]->setPoints(coos);
168              }
169            else
170              {
171                edgesmap[ei]->setPoints(coos,true);
172              }
173
174            //reposition of edgetext
175            xy<double> text_pos=edgesmap[ei]->getArrowPos();
176            text_pos+=(xy<double>(10,10));
177            edgetextmap[ei]->property_x().set_value(text_pos.x);
178            edgetextmap[ei]->property_y().set_value(text_pos.y);
179        }
180
181        mapstorage.graph.firstIn(ei,active_node);
182        for(;ei!=INVALID;mapstorage.graph.nextIn(ei))
183        {
184            Gnome::Canvas::Points coos;
185            double x1, x2, y1, y2;
186
187            nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
188            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
189
190            nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
191            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
192
193            if(isbutton==3)
194              {
195                edgesmap[ei]->setPoints(coos);
196              }
197            else
198              {
199                edgesmap[ei]->setPoints(coos,true);
200              }
201
202            xy<double> text_pos=edgesmap[ei]->getArrowPos();
203            text_pos+=(xy<double>(10,10));
204            edgetextmap[ei]->property_x().set_value(text_pos.x);
205            edgetextmap[ei]->property_y().set_value(text_pos.y);
206        }
207      }
208    default: break;
209  }
210
211  return false;
212}
213
214bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
215{
216  switch(e->type)
217  {
218    //move the new node
219    case GDK_MOTION_NOTIFY:
220      {
221        GdkEvent * generated=new GdkEvent();
222        generated->motion.x=e->motion.x;
223        generated->motion.y=e->motion.y;
224        generated->type=GDK_MOTION_NOTIFY;
225        moveEventHandler(generated);     
226        break;
227      }
228
229    case GDK_BUTTON_RELEASE:
230      mapstorage.modified = true;
231
232      isbutton=1;
233
234      active_node=mapstorage.graph.addNode();
235
236      //initiating values corresponding to new node in maps
237
238      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
239
240      // update coordinates
241      mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
242
243      // update id map
244      (*mapstorage.nodemap_storage["id"])[active_node] =
245        mapstorage.graph.id(active_node);
246
247      // update all other maps
248      for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
249          mapstorage.nodemap_storage.begin(); it !=
250          mapstorage.nodemap_storage.end(); ++it)
251      {
252        if ((it->first != "id") &&
253            (it->first != "coordinates_x") &&
254            (it->first != "coordiantes_y"))
255        {
256          (*(it->second))[active_node] =
257            mapstorage.nodemap_default[it->first];
258        }
259      }
260
261      nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
262          clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
263      active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
264      *(nodesmap[active_node]) <<
265        Gnome::Canvas::Properties::fill_color("blue");
266      *(nodesmap[active_node]) <<
267        Gnome::Canvas::Properties::outline_color("black");
268      active_item->raise_to_top();
269
270      (nodesmap[active_node])->show();
271
272      nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph,
273          clicked_x+node_property_defaults[N_RADIUS]+5,
274          clicked_y+node_property_defaults[N_RADIUS]+5, "");
275      nodetextmap[active_node]->property_fill_color().set_value("darkblue");
276      nodetextmap[active_node]->raise_to_top();
277
278      mapwin.updateNode(active_node);
279
280      isbutton=0;
281      target_item=NULL;
282      active_item=NULL;
283      active_node=INVALID;
284
285      break;
286    default:
287      break;
288  }
289  return false;
290}
291
292bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
293{
294  switch(e->type)
295  {
296    case GDK_BUTTON_PRESS:
297      //in edge creation right button has special meaning
298      if(e->button.button!=3)
299      {
300        //there is not yet selected node
301        if(active_node==INVALID)
302        {
303          //we mark the location of the event to be able to calculate parameters of dragging
304
305          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
306
307          active_item=(get_item_at(clicked_x, clicked_y));
308          active_node=INVALID;
309          for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
310          {
311            if(nodesmap[i]==active_item)
312            {
313              active_node=i;
314            }
315          }
316          //the clicked item is really a node
317          if(active_node!=INVALID)
318          {
319            *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
320            isbutton=1;
321          }
322          //clicked item was not a node. It could be e.g. edge.
323          else
324          {
325            active_item=NULL;
326          }
327        }
328        //we only have to do sg. if the mouse button
329        // is pressed already once AND the click was
330        // on a node that was found in the set of
331        //nodes, and now we only search for the second
332        //node
333        else
334        {
335          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
336          target_item=(get_item_at(clicked_x, clicked_y));
337          Node target_node=INVALID;
338          for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
339          {
340            if(nodesmap[i]==target_item)
341            {
342              target_node=i;
343            }
344          }
345          //the clicked item is a node, the edge can be drawn
346          if(target_node!=INVALID)
347          {
348            if(target_node!=active_node)               
349            {
350              mapstorage.modified = true;
351
352              *(nodesmap[target_node]) <<
353                Gnome::Canvas::Properties::fill_color("red");
354
355              //creating new edge
356              active_edge=mapstorage.graph.addEdge(active_node,
357                  target_node);
358
359              // update id map
360              (*mapstorage.edgemap_storage["id"])[active_edge] =
361                mapstorage.graph.id(active_edge);
362 
363              // update all other maps
364              for (std::map<std::string,
365                  Graph::EdgeMap<double>*>::const_iterator it =
366                  mapstorage.edgemap_storage.begin(); it !=
367                  mapstorage.edgemap_storage.end(); ++it)
368              {
369                if (it->first != "id")
370                {
371                  (*(it->second))[active_edge] =
372                    mapstorage.edgemap_default[it->first];
373                }
374              }
375
376              //calculating coordinates of new edge
377              Gnome::Canvas::Points coos;
378              double x1, x2, y1, y2;
379
380              active_item->get_bounds(x1, y1, x2, y2);
381              coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
382
383              target_item->get_bounds(x1, y1, x2, y2);
384              coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
385
386              //drawing new edge
387              edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos,
388                  *this);
389              *(edgesmap[active_edge]) <<
390                Gnome::Canvas::Properties::fill_color("green");
391              edgesmap[active_edge]->property_width_pixels().set_value(10);
392
393              edgesmap[active_edge]->lower_to_bottom();
394
395              //initializing edge-text as well, to empty string
396              xy<double> text_pos=edgesmap[active_edge]->getArrowPos();
397              text_pos+=(xy<double>(10,10));
398
399              edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
400                  text_pos.x, text_pos.y, "");
401              edgetextmap[active_edge]->property_fill_color().set_value(
402                  "darkgreen");
403              edgetextmap[active_edge]->raise_to_top();
404
405              //updating its properties
406              mapwin.updateEdge(active_edge);
407            }
408            else
409            {
410              target_node=INVALID;
411              std::cerr << "Loop edge is not yet implemented!" << std::endl;
412            }
413          }
414          //clicked item was not a node. it could be an e.g. edge. we do not
415          //deal with it furthermore.
416          else
417          {
418            target_item=NULL;
419          }
420        }
421      }
422      break;
423    case GDK_BUTTON_RELEASE:
424      isbutton=0;
425      //we clear settings in two cases
426      //1: the edge is ready (target_item has valid value)
427      //2: the edge creation is cancelled with right button
428      if((target_item)||(e->button.button==3))
429      {
430        if(active_item)
431        {
432          *active_item << Gnome::Canvas::Properties::fill_color("blue");
433          active_item=NULL;
434        }
435        if(target_item)
436        {
437          *target_item << Gnome::Canvas::Properties::fill_color("blue");
438          target_item=NULL;
439        }
440        active_node=INVALID;
441        active_edge=INVALID;
442      }
443      break;
444    default:
445      break;
446  }
447  return false;
448}
449
450bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
451{
452  switch(e->type)
453    {
454    case GDK_BUTTON_PRESS:
455      //finding the clicked items
456      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
457      active_item=(get_item_at(clicked_x, clicked_y));
458      active_node=INVALID;
459      active_edge=INVALID;
460      //was it a node?
461      for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
462        {
463          if(nodesmap[i]==active_item)
464            {
465              active_node=i;
466            }
467        }
468      //or was it an edge?
469      if(active_node==INVALID)
470        {
471          for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
472            {
473              if(edgesmap[i]==active_item)
474                {
475                  active_edge=i;
476                }
477            }
478        }
479
480      //recolor activated item
481      if(active_item)
482        {
483          *active_item << Gnome::Canvas::Properties::fill_color("red");
484        }
485      break;
486
487    case GDK_BUTTON_RELEASE:
488      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
489      if(active_item)
490        {
491          //the cursor was not moved since pressing it
492          if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
493            {
494              //a node was found
495              if(active_node!=INVALID)
496                {
497                  mapstorage.modified = true;
498
499                  //collecting edges to delete
500                  EdgeIt e;
501                  std::set<Graph::Edge> edges_to_delete;
502
503                  mapstorage.graph.firstOut(e,active_node);
504                  for(;e!=INVALID;mapstorage.graph.nextOut(e))
505                    {
506                      edges_to_delete.insert(e);
507                    }
508
509                  mapstorage.graph.firstIn(e,active_node);
510                  for(;e!=INVALID;mapstorage.graph.nextIn(e))
511                    {
512                      edges_to_delete.insert(e);
513                    }
514
515                  //deleting collected edges
516                  for(std::set<Graph::Edge>::iterator edge_set_it=edges_to_delete.begin();edge_set_it!=edges_to_delete.end();edge_set_it++)
517                    {
518                      deleteItem(*edge_set_it);
519                    }
520                  deleteItem(active_node);
521                }
522              //a simple edge was chosen
523              else
524                {
525                  deleteItem(active_edge);
526                }
527            }
528          //pointer was moved, deletion is cancelled
529          else
530            {
531              if(active_node!=INVALID)
532                {
533                  *active_item << Gnome::Canvas::Properties::fill_color("blue");
534                }
535              else
536                {
537                  *active_item << Gnome::Canvas::Properties::fill_color("green");
538                }
539            }
540        }
541      //reseting datas
542      active_item=NULL;
543      active_edge=INVALID;
544      active_node=INVALID;
545      break;
546
547    case GDK_MOTION_NOTIFY:
548      break;
549
550    default:
551      break;
552    }
553  return false;
554}
555
556bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
557{
558  if(actual_tool==EDGE_MAP_EDIT)
559    {
560      switch(e->type)
561        {
562        case GDK_KEY_PRESS:
563          //for Escape or Enter hide the displayed widget
564          {
565            nodeMapEditEventHandler(e);
566            break;
567          }
568        case GDK_BUTTON_PRESS:
569          //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
570          {
571            //for determine, whether it was an edge
572            Edge clicked_edge=INVALID;
573
574            //find the activated item between texts
575            active_item=(get_item_at(e->button.x, e->button.y));
576            for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
577              {
578                if(edgetextmap[i]==active_item)
579                  {
580                    clicked_edge=i;
581                  }
582              }
583
584            //if it was not between texts, search for it between edges
585            if(clicked_edge==INVALID)
586              {
587                window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
588                active_item=(get_item_at(clicked_x, clicked_y));
589
590                for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
591                  {
592                    //at the same time only one can be active
593                    if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
594                      {
595                        clicked_edge=i;
596                      }
597                  }
598              }
599            //if it was really an edge...
600            if(clicked_edge!=INVALID)
601              {
602                // the id map is not editable
603                if (nodemap_to_edit == "id") return 0;
604                //If there is already edited edge, it has to be saved first
605                if(entrywidget.is_visible())
606                  {
607                    GdkEvent * generated=new GdkEvent();
608                    generated->type=GDK_KEY_PRESS;
609                    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
610                    entryWidgetChangeHandler(generated);
611                  }
612                //If the previous value could be saved, we can go further, otherwise not
613                if(!entrywidget.is_visible())
614                  {
615                    //and there is activated map
616                    if(edgetextmap[clicked_edge]->property_text().get_value()!="")
617                      {
618                        //activate the general variable for it
619                        active_edge=clicked_edge;
620                        //delete visible widget if there is
621                        if(canvasentrywidget)
622                          {
623                            delete(canvasentrywidget);
624                          }
625
626                        //initialize the entry
627                        entrywidget.show();
628
629                        //fill in the correct value
630                        entrywidget.set_text(edgetextmap[active_edge]->property_text().get_value());
631
632                        //replace and resize the entry to the activated edge and put it in a Canvas::Widget to be able to display it on gdc
633                        xy<double> entry_coos;
634                        entry_coos.x=(edgetextmap[active_edge])->property_x().get_value();
635                        entry_coos.x-=edgetextmap[active_edge]->property_text_width().get_value()/2;
636                        entry_coos.y=(edgetextmap[active_edge])->property_y().get_value();
637                        entry_coos.y-=edgetextmap[active_edge]->property_text_height().get_value()*1.5/2;
638                        canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
639                        canvasentrywidget->property_width().set_value(edgetextmap[active_edge]->property_text_width().get_value()*4);
640                        canvasentrywidget->property_height().set_value(edgetextmap[active_edge]->property_text_height().get_value()*1.5);
641
642                        //setting the focus to newly created widget
643                        parentwin->set_focus(entrywidget);
644                        parentwin->activate_focus();
645                      }
646                  }
647              }
648            //if it was not an edge...
649            else
650              {
651                //In this case the click did not happen on an edge
652                //if there is visible entry we save the value in it
653                //we pretend like an Enter was presse din the Entry widget
654                GdkEvent * generated=new GdkEvent();
655                generated->type=GDK_KEY_PRESS;
656                ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
657                entryWidgetChangeHandler(generated);
658              }
659            break;
660          }
661        default:
662          break;
663        }
664    }
665  return false; 
666}
667
668bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
669{
670  if(actual_tool==NODE_MAP_EDIT)
671    {
672      switch(e->type)
673        {
674        case GDK_KEY_PRESS:
675          //for Escape or Enter hide the displayed widget
676          {
677            switch(((GdkEventKey*)e)->keyval)
678              {
679              case GDK_Escape:
680                entrywidget.hide();
681                break;
682              case GDK_Return:
683              case GDK_KP_Enter:
684                entrywidget.hide();
685                break;
686              default:
687                break;
688              }
689 
690            break;
691          }
692        case GDK_BUTTON_PRESS:
693          //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
694          {
695            //for determine, whether it was a node
696            Node clicked_node=INVALID;
697
698            //find the activated item between texts
699            active_item=(get_item_at(e->button.x, e->button.y));
700            for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
701              {
702                //at the same time only one can be active
703                if(nodetextmap[i]==active_item)
704                  {
705                    clicked_node=i;
706                  }
707              }
708
709            //if there was not, search for it between nodes
710            if(clicked_node==INVALID)
711              {
712                window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
713                active_item=(get_item_at(clicked_x, clicked_y));
714
715                for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
716                  {
717                    //at the same time only one can be active
718                    if(nodesmap[i]==active_item)
719                      {
720                        clicked_node=i;
721                      }
722                  }
723              }
724            //if it was really an edge...
725            if(clicked_node!=INVALID)
726              {
727                // the id map is not editable
728                if (nodemap_to_edit == "id") return 0;
729                //If there is already edited edge, it has to be saved first
730                if(entrywidget.is_visible())
731                  {
732                    GdkEvent * generated=new GdkEvent();
733                    generated->type=GDK_KEY_PRESS;
734                    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
735                    entryWidgetChangeHandler(generated);
736                  }
737                //If the previous value could be saved, we can go further, otherwise not
738                if(!entrywidget.is_visible())
739                  {
740                    //and there is activated map
741                    if(nodetextmap[clicked_node]->property_text().get_value()!="")
742                      {
743                        //activate the general variable for it
744                        active_node=clicked_node;
745                        //delete visible widget if there is
746                        if(canvasentrywidget)
747                          {
748                            delete(canvasentrywidget);
749                          }
750
751                        //initialize the entry
752                        entrywidget.show();
753
754                        //fill in the correct value
755                        entrywidget.set_text(nodetextmap[active_node]->property_text().get_value());
756
757                        //replace and resize the entry to the activated node and put it in a Canvas::Widget to be able to display it on gdc
758                        xy<double> entry_coos;
759                        entry_coos.x=(nodetextmap[active_node])->property_x().get_value();
760                        entry_coos.x-=nodetextmap[active_node]->property_text_width().get_value()/2;
761                        entry_coos.y=(nodetextmap[active_node])->property_y().get_value();
762                        entry_coos.y-=nodetextmap[active_node]->property_text_height().get_value()*1.5/2;
763                        canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
764                        canvasentrywidget->property_width().set_value(nodetextmap[active_node]->property_text_width().get_value()*4);
765                        canvasentrywidget->property_height().set_value(nodetextmap[active_node]->property_text_height().get_value()*1.5);
766                      }
767                  }
768              }
769            //if it was not an edge...
770            else
771              {
772                //In this case the click did not happen on an edge
773                //if there is visible entry we save the value in it
774                //we pretend like an Enter was presse din the Entry widget
775                GdkEvent * generated=new GdkEvent();
776                generated->type=GDK_KEY_PRESS;
777                ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
778                entryWidgetChangeHandler(generated);
779              }
780            break;
781          }
782        default:
783          break;
784        }
785    }
786  return false; 
787}
788
789bool GraphDisplayerCanvas::entryWidgetChangeHandler(GdkEvent* e)
790{
791  if(entrywidget.is_visible())
792    {
793      if(e->type==GDK_KEY_PRESS)
794        {
795          switch(((GdkEventKey*)e)->keyval)
796            {
797            case GDK_Escape:
798              entrywidget.hide();
799              break;
800            case GDK_KP_Enter:
801            case GDK_Return:
802              {
803                //these variables check whether the text in the entry is valid
804                bool valid_double=true;
805                int point_num=0;
806
807                //getting the value from the entry and converting it to double
808                Glib::ustring mapvalue_str = entrywidget.get_text();
809
810                char * mapvalue_ch=new char [mapvalue_str.length()];
811                for(int i=0;i<(int)(mapvalue_str.length());i++)
812                  {
813                    if(((mapvalue_str[i]<'0')||(mapvalue_str[i]>'9'))&&(mapvalue_str[i]!='.'))
814                      {
815                        valid_double=false;
816                      }
817                    else
818                      {
819                        if(mapvalue_str[i]=='.')
820                          {
821                            point_num++;
822                          }
823                      }
824                    mapvalue_ch[i]=mapvalue_str[i];
825                  }
826             
827                //if the text in the entry was correct
828                if((point_num<=1)&&(valid_double))
829                  {
830                    double mapvalue_d=atof(mapvalue_ch);
831
832                    //reconvert the double to string for the correct format
833                    std::ostringstream ostr;
834                    ostr << mapvalue_d;
835
836                    //save the value to the correct place
837                    switch(actual_tool)
838                      {
839                      case EDGE_MAP_EDIT:
840                        edgetextmap[active_edge]->property_text().set_value(ostr.str());
841                        (*(mapstorage.edgemap_storage)[edgemap_to_edit])[active_edge]=mapvalue_d;
842                        mapwin.updateEdge(active_edge);
843                        break;
844                      case NODE_MAP_EDIT:
845                        nodetextmap[active_node]->property_text().set_value(ostr.str());
846                        (*(mapstorage.nodemap_storage)[nodemap_to_edit])[active_node]=mapvalue_d;
847                        mapwin.updateNode(active_node);
848                        break;
849                      default:
850                        break;
851                      }
852                    entrywidget.hide();
853                  }
854                //the text in the entry was not correct for a double
855                else
856                  {
857                    std::cerr << "ERROR: only handling of double values is implemented yet!" << std::endl;
858                  }
859
860                break;
861              }
862            default:
863              break;
864            }
865        }
866    }
867  return false;
868}
869
870void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
871{
872  delete(nodetextmap[node_to_delete]);
873  delete(nodesmap[node_to_delete]);
874  mapstorage.graph.erase(node_to_delete);
875}
876
877void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
878{
879  delete(edgetextmap[edge_to_delete]);
880  delete(edgesmap[edge_to_delete]);
881  mapstorage.graph.erase(edge_to_delete);
882}
883
884void GraphDisplayerCanvas::textReposition(xy<double> new_place)
885{
886  new_place+=(xy<double>(10,10));
887  edgetextmap[forming_edge]->property_x().set_value(new_place.x);
888  edgetextmap[forming_edge]->property_y().set_value(new_place.y);
889}
890
891void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
892{
893  if(on)
894    {
895      if(forming_edge!=INVALID)
896        {
897          std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
898        }
899      else
900        {
901          for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
902            {
903              if(edgesmap[i]==active_bre)
904                {
905                  forming_edge=i;
906                }
907            }
908        }
909    }
910  else
911    {
912      if(forming_edge!=INVALID)
913        {
914          forming_edge=INVALID;
915        }
916      else
917        {
918          std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
919        }
920    }
921
922}
923
924int GraphDisplayerCanvas::addNewEdgeMap(double default_value, std::string mapname)
925{
926  //create the new map
927  Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mapstorage.graph, default_value);
928
929  //if addition was not successful addEdgeMap returns one.
930  //cause can be that there is already a map named like the new one
931  if(mapstorage.addEdgeMap(mapname,emptr, default_value))
932    {
933      return 1;
934    }
935
936
937  //add it to the list of the displayable maps
938  mapwin.registerNewEdgeMap(mapname);
939
940  //display it
941  changeEdgeText(mapname);
942
943  return 0;
944}
945
946int GraphDisplayerCanvas::addNewNodeMap(double default_value, std::string mapname)
947{
948  //create the new map
949  Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mapstorage.graph,default_value);
950
951  //if addition was not successful addNodeMap returns one.
952  //cause can be that there is already a map named like the new one
953  if(mapstorage.addNodeMap(mapname,emptr, default_value))
954    {
955      return 1;
956    }
957
958  //add it to the list of the displayable maps
959  mapwin.registerNewNodeMap(mapname);
960
961  //display it
962  changeNodeText(mapname);
963
964  return 0;
965}
966
Note: See TracBrowser for help on using the repository browser.