COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas-event.cc @ 148:5adf29662354

Last change on this file since 148:5adf29662354 was 148:5adf29662354, checked in by Hegyi Péter, 18 years ago

When moving nodes with midbutton little red arrows keep their position.

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