COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas-event.cc @ 55:e4ee805ca5fc

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

Alpar had the key, focus can be set in the window class. But it is not enough, the focused widget has to be activated, as well! Was a hard task to find out... By the way, two compilation warnings are removed.

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