COIN-OR::LEMON - Graph Library

source: glemon-0.x/graph_displayer_canvas-event.cc @ 160:14a76109b561

Last change on this file since 160:14a76109b561 was 160:14a76109b561, checked in by Hegyi Péter, 18 years ago

Node antigravity and edge elasticity based graph layout redesigner.

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