COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas-event.cc @ 48:b8ec84524fa2

gui
Last change on this file since 48:b8ec84524fa2 was 48:b8ec84524fa2, checked in by Hegyi Péter, 19 years ago

cout->cerr, node radius and edge width is now scaled, maps are editable by clicking on texts.

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