Save and load the coordinates of the arrows on the edges.
authorladanyi
Sat, 17 Dec 2005 20:55:41 +0000
changeset 186027a9a75b957b
parent 1859 075aaa0a4e6f
child 1861 5f204c7a1318
Save and load the coordinates of the arrows on the edges.
gui/Makefile.am
gui/all_include.h
gui/gdc-broken_edge.cc
gui/graph_displayer_canvas-event.cc
gui/graph_displayer_canvas.cc
gui/graph_displayer_canvas.h
gui/gui_reader.cc
gui/gui_reader.h
gui/gui_writer.cc
gui/gui_writer.h
gui/mapstorage.cc
gui/mapstorage.h
gui/xymap.h
     1.1 --- a/gui/Makefile.am	Wed Dec 14 18:11:03 2005 +0000
     1.2 +++ b/gui/Makefile.am	Sat Dec 17 20:55:41 2005 +0000
     1.3 @@ -28,6 +28,10 @@
     1.4  	new_map_win.cc \
     1.5  	new_map_win.h \
     1.6  	xymap.h \
     1.7 +	gui_reader.h \
     1.8 +	gui_reader.cc \
     1.9 +	gui_writer.h \
    1.10 +	gui_writer.cc \
    1.11  	icons/guipixbufs.h
    1.12  
    1.13  
     2.1 --- a/gui/all_include.h	Wed Dec 14 18:11:03 2005 +0000
     2.2 +++ b/gui/all_include.h	Sat Dec 17 20:55:41 2005 +0000
     2.3 @@ -37,9 +37,8 @@
     2.4  
     2.5  using namespace lemon;
     2.6  
     2.7 -typedef xy<double> Coordinates;
     2.8 +typedef xy<double> XY;
     2.9  typedef ListGraph Graph;
    2.10 -typedef Graph::NodeMap<Coordinates> CoordinatesMap;
    2.11  typedef Graph::Node Node;
    2.12  typedef Graph::Edge Edge;
    2.13  typedef Graph::EdgeIt EdgeIt;
     3.1 --- a/gui/gdc-broken_edge.cc	Wed Dec 14 18:11:03 2005 +0000
     3.2 +++ b/gui/gdc-broken_edge.cc	Sat Dec 17 20:55:41 2005 +0000
     3.3 @@ -1,15 +1,13 @@
     3.4  #include "graph_displayer_canvas.h"
     3.5  #include <cmath>
     3.6  
     3.7 -GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Gnome::Canvas::Points p, GraphDisplayerCanvas & gc) : Line(g), gdc(gc), isbutton(false)
     3.8 +GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc) : Line(g), edge(_edge), gdc(gc), isbutton(false)
     3.9  {
    3.10 -  my_points=new Gnome::Art::Point[3];
    3.11 -
    3.12    arrow=new Gnome::Canvas::Polygon(g);
    3.13    *arrow << Gnome::Canvas::Properties::fill_color("red");
    3.14    arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
    3.15    arrow->lower_to_bottom();
    3.16 -  setPoints(p);
    3.17 +  draw();
    3.18  }
    3.19  
    3.20  GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
    3.21 @@ -17,155 +15,71 @@
    3.22    if(arrow)delete(arrow);
    3.23  }
    3.24  
    3.25 -void GraphDisplayerCanvas::BrokenEdge::setPoints(Gnome::Canvas::Points p, bool move)
    3.26 +void GraphDisplayerCanvas::BrokenEdge::draw()
    3.27  {
    3.28 -  bool set_arrow=false;
    3.29 -  //red arrow losts its position-right button
    3.30 -  if(!move)
    3.31 -    {
    3.32 -      if(p.size()==2)
    3.33 -	{
    3.34 -	  set_arrow=true;
    3.35 -	  Gnome::Canvas::Points points_with_center;
    3.36 -	  points_with_center.push_back(my_points[0]=p[0]);
    3.37 -	  points_with_center.push_back(my_points[1]=Gnome::Art::Point( (p[0].get_x()+p[1].get_x())/2+0 , (p[0].get_y()+p[1].get_y())/2 )+0 );
    3.38 -	  points_with_center.push_back(my_points[2]=p[1]);
    3.39 -	  property_points().set_value(points_with_center);
    3.40 -	}  
    3.41 -      if(p.size()==3)
    3.42 -	{
    3.43 -	  set_arrow=true;
    3.44 -	  property_points().set_value(p);
    3.45 -	  for(int i=0;i<3;i++)
    3.46 -	    {
    3.47 -	      my_points[i]=p[i];
    3.48 -	    }
    3.49 -	}
    3.50 +  MapStorage& ms = gdc.mytab.mapstorage;
    3.51 +
    3.52 +  // update the edge
    3.53 +  {
    3.54 +    Gnome::Canvas::Points points;
    3.55 +    Node source = ms.graph.source(edge);
    3.56 +    Node target = ms.graph.target(edge);
    3.57 +    points.push_back(Gnome::Art::Point(ms.coords[source].x,
    3.58 +          ms.coords[source].y));
    3.59 +    points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
    3.60 +          ms.arrow_pos[edge].y));
    3.61 +    points.push_back(Gnome::Art::Point(ms.coords[target].x,
    3.62 +          ms.coords[target].y));
    3.63 +    property_points().set_value(points);
    3.64 +  }
    3.65 +
    3.66 +  // update the arrow
    3.67 +  {
    3.68 +    //calculating coordinates of the direction indicator arrow
    3.69 +    XY target(ms.coords[ms.graph.target(edge)]);
    3.70 +    XY center(ms.arrow_pos[edge]);
    3.71 +
    3.72 +    XY unit_vector_in_dir(target-center);
    3.73 +    double length=sqrt( unit_vector_in_dir.normSquare() );
    3.74 +
    3.75 +    //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
    3.76 +    unit_vector_in_dir/=length;
    3.77 +    //       std::cout << " = " << unit_vector_in_dir << std::endl;
    3.78 +
    3.79 +    XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
    3.80 +    //       std::cout << unit_norm_vector << std::endl;
    3.81 +
    3.82 +    {      
    3.83 +      //       /\       // top
    3.84 +      //      /  \      //
    3.85 +      //      -  -      // c(enter)l(eft), ccl, ccr, cr
    3.86 +      //       ||       //
    3.87 +      //       ||       // b(ottom)l, br
    3.88      }
    3.89 -  else
    3.90 -    {
    3.91 -      //arrow keeps its position-left button
    3.92  
    3.93 -//       if(p.size()==2)
    3.94 -//       	{
    3.95 -//       	  Gnome::Canvas::Points points;
    3.96 -//       	  my_points[0]=p[0];
    3.97 -//       	  my_points[2]=p[1];
    3.98 -//       	  for(int i=0;i<3;i++)
    3.99 -//       	    {
   3.100 -//       	      points.push_back(my_points[i]);
   3.101 -//       	    }
   3.102 -//       	  property_points().set_value(points);
   3.103 -//       	}
   3.104 -      set_arrow=true;
   3.105 +    double size=3;
   3.106  
   3.107 -      //////////////////////////////////////////////////////////////////////////////////////////////////////
   3.108 -      /////////// keeps shape-with scalar multiplication - version 2.
   3.109 -      //////////////////////////////////////////////////////////////////////////////////////////////////////
   3.110 +    XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
   3.111 +    XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
   3.112 +    XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
   3.113 +    XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
   3.114 +    XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
   3.115 +    XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
   3.116 +    XY top(center + unit_vector_in_dir * 3 * size);
   3.117  
   3.118 -      if(p.size()==2)
   3.119 -      	{
   3.120 -	  //old vector from one to the other node - a
   3.121 -	  xy<double> a_v(my_points[2].get_x()-my_points[0].get_x(),my_points[2].get_y()-my_points[0].get_y());
   3.122 -	  //new vector from one to the other node - b
   3.123 -	  xy<double> b_v(p[1].get_x()-p[0].get_x(),p[1].get_y()-p[0].get_y());
   3.124 +    //std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
   3.125  
   3.126 -	  double absa=sqrt(a_v.normSquare());
   3.127 -	  double absb=sqrt(b_v.normSquare());
   3.128 +    Gnome::Canvas::Points arrow_points;
   3.129 +    arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
   3.130 +    arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
   3.131 +    arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
   3.132 +    arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
   3.133 +    arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
   3.134 +    arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
   3.135 +    arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
   3.136  
   3.137 -	  if((absa!=0)&&(absb!=0))
   3.138 -	    {
   3.139 -	      //old vector from one node to the breakpoint - c
   3.140 -	      xy<double> c_v(my_points[1].get_x()-my_points[0].get_x(),my_points[1].get_y()-my_points[0].get_y());
   3.141 -
   3.142 -	      //unit vector with the same direction to a_v
   3.143 -	      xy<double> a_v_u(a_v.x/absa,a_v.y/absa);
   3.144 -
   3.145 -	      //normal vector of unit vector with the same direction to a_v
   3.146 -	      xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
   3.147 -
   3.148 -	      //unit vector with the same direction to b_v
   3.149 -	      xy<double> b_v_u(b_v.x/absb,b_v.y/absb);
   3.150 -
   3.151 -	      //normal vector of unit vector with the same direction to b_v
   3.152 -	      xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
   3.153 -
   3.154 -	      //vector c in a_v_u and a_v_u_n co-ordinate system
   3.155 -	      xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n);
   3.156 -
   3.157 -	      //new vector from one node to the breakpoint - d - we have to calculate this one
   3.158 -	      xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
   3.159 -
   3.160 -	      my_points[1]=Gnome::Art::Point(d_v.x+p[0].get_x(),d_v.y+p[0].get_y());
   3.161 -
   3.162 -	      my_points[0]=p[0];
   3.163 -	      my_points[2]=p[1];
   3.164 -	  
   3.165 -	      Gnome::Canvas::Points points;
   3.166 -	      for(int i=0;i<3;i++)
   3.167 -		{
   3.168 -		  points.push_back(my_points[i]);
   3.169 -		}
   3.170 -	      property_points().set_value(points);
   3.171 -	    }
   3.172 -	  else
   3.173 -	    {
   3.174 -	      //if distance is 0, segmentation would be occured
   3.175 -	      //in calculations, because of division by zero
   3.176 -	      //But we have luck: the edge cannot be seen in
   3.177 -	      //this case, so no update needed
   3.178 -	      set_arrow=false;
   3.179 -	    }
   3.180 -	}
   3.181 -    }
   3.182 -  if(set_arrow)
   3.183 -    {
   3.184 -      //calculating coordinates of the direction indicator arrow
   3.185 -
   3.186 -      xy<gdouble> target( my_points[2].get_x(), my_points[2].get_y() );
   3.187 -      xy<gdouble> center( my_points[1].get_x(), my_points[1].get_y() );
   3.188 -
   3.189 -      xy<gdouble> unit_vector_in_dir(target-center);
   3.190 -      double length=sqrt( unit_vector_in_dir.normSquare() );
   3.191 -
   3.192 -      //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
   3.193 -      unit_vector_in_dir/=length;
   3.194 -      //       std::cout << " = " << unit_vector_in_dir << std::endl;
   3.195 -
   3.196 -      xy<gdouble> unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
   3.197 -      //       std::cout << unit_norm_vector << std::endl;
   3.198 -
   3.199 -      {      
   3.200 -	//       /\       // top
   3.201 -	//      /  \      //
   3.202 -	//      -  -      // c(enter)l(eft), ccl, ccr, cr
   3.203 -	//       ||       //
   3.204 -	//       ||       // b(ottom)l, br
   3.205 -      }
   3.206 -
   3.207 -      double size=3;
   3.208 -
   3.209 -      xy<gdouble> bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
   3.210 -      xy<gdouble> br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
   3.211 -      xy<gdouble> ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
   3.212 -      xy<gdouble> ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
   3.213 -      xy<gdouble> cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
   3.214 -      xy<gdouble> cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
   3.215 -      xy<gdouble> top(center + unit_vector_in_dir * 3 * size);
   3.216 -	 
   3.217 -      //std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
   3.218 -
   3.219 -      Gnome::Canvas::Points arrow_points;
   3.220 -      arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
   3.221 -      arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
   3.222 -      arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
   3.223 -      arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
   3.224 -      arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
   3.225 -      arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
   3.226 -      arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
   3.227 -
   3.228 -      arrow->property_points().set_value(arrow_points);
   3.229 -    }
   3.230 +    arrow->property_points().set_value(arrow_points);
   3.231 +  }
   3.232  }
   3.233  
   3.234  bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
   3.235 @@ -203,12 +117,10 @@
   3.236  
   3.237  	  Gnome::Canvas::Points points_new;
   3.238  
   3.239 -	  points_new.push_back(my_points[0]);
   3.240 -	  points_new.push_back(my_points[1]=Gnome::Art::Point(my_points[1].get_x()+dx,my_points[1].get_y()+dy));
   3.241 -	  points_new.push_back(my_points[2]);
   3.242 +          gdc.mytab.mapstorage.arrow_pos.set(edge, gdc.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
   3.243  
   3.244 -	  setPoints(points_new);
   3.245 -	  gdc.textReposition(xy<double>(my_points[1].get_x(),my_points[1].get_y()));
   3.246 +	  draw();
   3.247 +	  gdc.textReposition(gdc.mytab.mapstorage.arrow_pos[edge]);
   3.248  
   3.249  	  clicked_x=e->motion.x;
   3.250  	  clicked_y=e->motion.y;
   3.251 @@ -219,9 +131,3 @@
   3.252  
   3.253    return true;
   3.254  }
   3.255 -
   3.256 -xy<double> GraphDisplayerCanvas::BrokenEdge::getArrowPos()
   3.257 -{
   3.258 -  xy<double> ret_val(my_points[1].get_x(),my_points[1].get_y());
   3.259 -  return ret_val;
   3.260 -}
     4.1 --- a/gui/graph_displayer_canvas-event.cc	Wed Dec 14 18:11:03 2005 +0000
     4.2 +++ b/gui/graph_displayer_canvas-event.cc	Sat Dec 17 20:55:41 2005 +0000
     4.3 @@ -147,12 +147,12 @@
     4.4          double coord_x = new_x - (clicked_x - (mytab.mapstorage).coords[active_node].x);
     4.5          double coord_y = new_y - (clicked_y - (mytab.mapstorage).coords[active_node].y);
     4.6  
     4.7 +        // write back the new coordinates to the coords map
     4.8 +        (mytab.mapstorage).coords.set(active_node, xy<double>(coord_x, coord_y));
     4.9 +
    4.10          clicked_x=new_x;
    4.11          clicked_y=new_y;
    4.12  
    4.13 -        // write back the new coordinates to the coords map
    4.14 -        (mytab.mapstorage).coords.set(active_node, xy<double>(coord_x, coord_y));
    4.15 -
    4.16          // reposition the coordinates text
    4.17          std::ostringstream ostr;
    4.18          ostr << "(" <<
    4.19 @@ -183,53 +183,50 @@
    4.20  	//all the edges connected to the moved point has to be redrawn
    4.21          for(OutEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
    4.22          {
    4.23 -            Gnome::Canvas::Points coos;
    4.24 -            double x1, x2, y1, y2;
    4.25 +            XY moved_node_1(coord_x - dx, coord_y - dy);
    4.26 +            XY moved_node_2(coord_x, coord_y);
    4.27 +            Node target = mytab.mapstorage.graph.target(ei);
    4.28 +            XY fix_node(mytab.mapstorage.coords[target].x,
    4.29 +                        mytab.mapstorage.coords[target].y);
    4.30 +            XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
    4.31  
    4.32 -            nodesmap[(mytab.mapstorage).graph.source(ei)]->get_bounds(x1, y1, x2, y2);
    4.33 -            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
    4.34 +            XY arrow_pos;
    4.35 +	    if(isbutton==3)
    4.36 +              arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, false);
    4.37 +	    else
    4.38 +              arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, true);
    4.39  
    4.40 -            nodesmap[(mytab.mapstorage).graph.target(ei)]->get_bounds(x1, y1, x2, y2);
    4.41 -            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
    4.42 -
    4.43 -	    if(isbutton==3)
    4.44 -	      {
    4.45 -		edgesmap[ei]->setPoints(coos);
    4.46 -	      }
    4.47 -	    else
    4.48 -	      {
    4.49 -		edgesmap[ei]->setPoints(coos,true);
    4.50 -	      }
    4.51 +            mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
    4.52 +            edgesmap[ei]->draw();
    4.53  
    4.54  	    //reposition of edgetext
    4.55 -	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
    4.56 -	    text_pos+=(xy<double>(10,10));
    4.57 +	    XY text_pos=mytab.mapstorage.arrow_pos[ei];
    4.58 +	    text_pos+=(XY(10,10));
    4.59  	    edgetextmap[ei]->property_x().set_value(text_pos.x);
    4.60  	    edgetextmap[ei]->property_y().set_value(text_pos.y);
    4.61          }
    4.62  
    4.63          for(InEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
    4.64          {
    4.65 -            Gnome::Canvas::Points coos;
    4.66 -            double x1, x2, y1, y2;
    4.67 +            XY moved_node_1(coord_x - dx, coord_y - dy);
    4.68 +            XY moved_node_2(coord_x, coord_y);
    4.69 +            Node source = mytab.mapstorage.graph.source(ei);
    4.70 +            XY fix_node(mytab.mapstorage.coords[source].x,
    4.71 +                        mytab.mapstorage.coords[source].y);
    4.72 +            XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
    4.73  
    4.74 -            nodesmap[(mytab.mapstorage).graph.source(ei)]->get_bounds(x1, y1, x2, y2);
    4.75 -            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
    4.76 +            XY arrow_pos;
    4.77 +	    if(isbutton==3)
    4.78 +              arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, false);
    4.79 +	    else
    4.80 +              arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, true);
    4.81  
    4.82 -            nodesmap[(mytab.mapstorage).graph.target(ei)]->get_bounds(x1, y1, x2, y2);
    4.83 -            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
    4.84 +            mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
    4.85 +            edgesmap[ei]->draw();
    4.86  
    4.87 -	    if(isbutton==3)
    4.88 -	      {
    4.89 -		edgesmap[ei]->setPoints(coos);
    4.90 -	      }
    4.91 -	    else
    4.92 -	      {
    4.93 -		edgesmap[ei]->setPoints(coos,true);
    4.94 -	      }
    4.95 -
    4.96 -	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
    4.97 -	    text_pos+=(xy<double>(10,10));
    4.98 +	    //reposition of edgetext
    4.99 +	    XY text_pos=mytab.mapstorage.arrow_pos[ei];
   4.100 +	    text_pos+=(XY(10,10));
   4.101  	    edgetextmap[ei]->property_x().set_value(text_pos.x);
   4.102  	    edgetextmap[ei]->property_y().set_value(text_pos.y);
   4.103          }
   4.104 @@ -240,6 +237,58 @@
   4.105    return false;
   4.106  }
   4.107  
   4.108 +XY GraphDisplayerCanvas::calcArrowPos(XY moved_node_1, XY moved_node_2, XY fix_node, XY old_arrow_pos, bool move)
   4.109 +{
   4.110 +  if(!move)
   4.111 +  {
   4.112 +    return XY((moved_node_2.x + fix_node.x) / 2.0, (moved_node_2.y + fix_node.y) / 2.0);
   4.113 +  }
   4.114 +  else
   4.115 +  {
   4.116 +    //////////////////////////////////////////////////////////////////////////////////////////////////////
   4.117 +    /////////// keeps shape-with scalar multiplication - version 2.
   4.118 +    //////////////////////////////////////////////////////////////////////////////////////////////////////
   4.119 +
   4.120 +    //old vector from one to the other node - a
   4.121 +    xy<double> a_v(moved_node_1.x-fix_node.x,moved_node_1.y-fix_node.y);
   4.122 +    //new vector from one to the other node - b
   4.123 +    xy<double> b_v(moved_node_2.x-fix_node.x,moved_node_2.y-fix_node.y);
   4.124 +
   4.125 +    double absa=sqrt(a_v.normSquare());
   4.126 +    double absb=sqrt(b_v.normSquare());
   4.127 +
   4.128 +    if ((absa == 0.0) || (absb == 0.0))
   4.129 +    {
   4.130 +      return old_arrow_pos;
   4.131 +    }
   4.132 +    else
   4.133 +    {
   4.134 +      //old vector from one node to the breakpoint - c
   4.135 +      xy<double> c_v(old_arrow_pos.x-fix_node.x,old_arrow_pos.y-fix_node.y);
   4.136 +
   4.137 +      //unit vector with the same direction to a_v
   4.138 +      xy<double> a_v_u(a_v.x/absa,a_v.y/absa);
   4.139 +
   4.140 +      //normal vector of unit vector with the same direction to a_v
   4.141 +      xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
   4.142 +
   4.143 +      //unit vector with the same direction to b_v
   4.144 +      xy<double> b_v_u(b_v.x/absb,b_v.y/absb);
   4.145 +
   4.146 +      //normal vector of unit vector with the same direction to b_v
   4.147 +      xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
   4.148 +
   4.149 +      //vector c in a_v_u and a_v_u_n co-ordinate system
   4.150 +      xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n);
   4.151 +
   4.152 +      //new vector from one node to the breakpoint - d - we have to calculate this one
   4.153 +      xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
   4.154 +
   4.155 +      return XY(d_v.x+fix_node.x,d_v.y+fix_node.y);
   4.156 +    }
   4.157 +  }
   4.158 +}
   4.159 +
   4.160  bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
   4.161  {
   4.162    switch(e->type)
   4.163 @@ -405,7 +454,7 @@
   4.164                coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
   4.165  
   4.166                //drawing new edge
   4.167 -              edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos,
   4.168 +              edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge,
   4.169                    *this);
   4.170                *(edgesmap[active_edge]) <<
   4.171                  Gnome::Canvas::Properties::fill_color("green");
   4.172 @@ -414,8 +463,8 @@
   4.173                edgesmap[active_edge]->lower_to_bottom();
   4.174  
   4.175                //initializing edge-text as well, to empty string
   4.176 -              xy<double> text_pos=edgesmap[active_edge]->getArrowPos();
   4.177 -              text_pos+=(xy<double>(10,10));
   4.178 +              XY text_pos=mytab.mapstorage.arrow_pos[active_edge];
   4.179 +              text_pos+=(XY(10,10));
   4.180  
   4.181                edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
   4.182                    text_pos.x, text_pos.y, "");
     5.1 --- a/gui/graph_displayer_canvas.cc	Wed Dec 14 18:11:03 2005 +0000
     5.2 +++ b/gui/graph_displayer_canvas.cc	Sat Dec 17 20:55:41 2005 +0000
     5.3 @@ -168,15 +168,15 @@
     5.4            (mytab.mapstorage).coords[(mytab.mapstorage).graph.target(i)].x,
     5.5            (mytab.mapstorage).coords[(mytab.mapstorage).graph.target(i)].y));
     5.6      
     5.7 -    edgesmap[i]=new BrokenEdge(displayed_graph, coos, *this);
     5.8 +    edgesmap[i]=new BrokenEdge(displayed_graph, i, *this);
     5.9      *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");
    5.10      edgesmap[i]->property_width_units().set_value(10);    
    5.11      edgesmap[i]->lower_to_bottom();
    5.12      
    5.13      //initializing edge-text as well, to empty string
    5.14  
    5.15 -    xy<double> text_pos=edgesmap[i]->getArrowPos();
    5.16 -    text_pos+=(xy<double>(10,10));
    5.17 +    XY text_pos=mytab.mapstorage.arrow_pos[i];
    5.18 +    text_pos+=(XY(10,10));
    5.19  
    5.20      edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, "");
    5.21      edgetextmap[i]->property_fill_color().set_value("darkgreen");
     6.1 --- a/gui/graph_displayer_canvas.h	Wed Dec 14 18:11:03 2005 +0000
     6.2 +++ b/gui/graph_displayer_canvas.h	Sat Dec 17 20:55:41 2005 +0000
     6.3 @@ -14,12 +14,13 @@
     6.4  ///This class is the canvas, on which the graph can be drawn.
     6.5  class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
     6.6  {
     6.7 +  friend class BrokenEdge;
     6.8 +
     6.9    class BrokenEdge : public Gnome::Canvas::Line
    6.10    {
    6.11 +    Edge edge;
    6.12      GraphDisplayerCanvas & gdc;
    6.13      Gnome::Canvas::Polygon * arrow;
    6.14 -    Gnome::Art::Point * my_points;
    6.15 -
    6.16  
    6.17      ///Indicates whether the button of mouse is pressed or not
    6.18      bool isbutton;
    6.19 @@ -31,10 +32,9 @@
    6.20      ///event handler for forming edges
    6.21      bool edgeFormerEventHandler(GdkEvent*);
    6.22    public:
    6.23 -    BrokenEdge(Gnome::Canvas::Group &, Gnome::Canvas::Points, GraphDisplayerCanvas &);
    6.24 +    BrokenEdge(Gnome::Canvas::Group &, Edge, GraphDisplayerCanvas &);
    6.25      ~BrokenEdge();
    6.26 -    void setPoints(Gnome::Canvas::Points, bool move=false);
    6.27 -    xy<double> getArrowPos();
    6.28 +    void draw();
    6.29    };
    6.30    typedef Gnome::Canvas::CanvasAA Parent;
    6.31  
    6.32 @@ -200,6 +200,7 @@
    6.33    ///reference to the parent window
    6.34    NoteBookTab & mytab;
    6.35  
    6.36 +  XY GraphDisplayerCanvas::calcArrowPos(XY, XY, XY, XY, bool);
    6.37  };
    6.38  
    6.39  #endif //GRAPH_DISPLAYER_CANVAS_H
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/gui/gui_reader.cc	Sat Dec 17 20:55:41 2005 +0000
     7.3 @@ -0,0 +1,33 @@
     7.4 +#include "gui_reader.h"
     7.5 +#include "xml.h"
     7.6 +#include "mapstorage.h"
     7.7 +#include <lemon/xy.h>
     7.8 +#include <vector>
     7.9 +
    7.10 +bool GuiReader::header(const std::string& line)
    7.11 +{
    7.12 +  std::istringstream ls(line);
    7.13 +  std::string head;
    7.14 +  ls >> head;
    7.15 +  return head == "@gui";
    7.16 +}
    7.17 +
    7.18 +void GuiReader::read(std::istream& is)
    7.19 +{
    7.20 +  XmlIo x(is);
    7.21 +  std::map<int, xy<double> > m;
    7.22 +  x("arrow_pos", m);
    7.23 +
    7.24 +  if ((int)m.size() != countEdges(mapstorage->graph)) return;
    7.25 +
    7.26 +  for (EdgeIt e(mapstorage->graph); e != INVALID; ++e)
    7.27 +  {
    7.28 +    int edgeid = (int)(*mapstorage->edgemap_storage["id"])[e];
    7.29 +    mapstorage->arrow_pos.set(e, m[edgeid]);
    7.30 +  }
    7.31 +  mapstorage->ArrowPosReadOK();
    7.32 +}
    7.33 +
    7.34 +GuiReader::GuiReader(LemonReader& reader, MapStorage* ms) : Parent(reader), mapstorage(ms)
    7.35 +{
    7.36 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/gui/gui_reader.h	Sat Dec 17 20:55:41 2005 +0000
     8.3 @@ -0,0 +1,21 @@
     8.4 +#ifndef GUI_READER_H
     8.5 +#define GUI_READER_H
     8.6 +
     8.7 +#include "mapstorage.h"
     8.8 +#include <lemon/lemon_reader.h>
     8.9 +
    8.10 +using lemon::LemonReader;
    8.11 +
    8.12 +class GuiReader : public LemonReader::SectionReader
    8.13 +{
    8.14 +  private:
    8.15 +    MapStorage* mapstorage;
    8.16 +  protected:
    8.17 +    virtual bool header(const std::string&);
    8.18 +    virtual void read(std::istream&);
    8.19 +  public:
    8.20 +    typedef LemonReader::SectionReader Parent;
    8.21 +    GuiReader(LemonReader&, MapStorage*);
    8.22 +};
    8.23 +
    8.24 +#endif
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/gui/gui_writer.cc	Sat Dec 17 20:55:41 2005 +0000
     9.3 @@ -0,0 +1,26 @@
     9.4 +#include "gui_writer.h"
     9.5 +#include "xml.h"
     9.6 +#include "mapstorage.h"
     9.7 +#include <lemon/xy.h>
     9.8 +#include <vector>
     9.9 +
    9.10 +std::string GuiWriter::header()
    9.11 +{
    9.12 +  return "@gui";
    9.13 +}
    9.14 +
    9.15 +void GuiWriter::write(std::ostream& os)
    9.16 +{
    9.17 +  XmlIo x(os);
    9.18 +  std::map<int, xy<double> > m;
    9.19 +  for (EdgeIt e(mapstorage->graph); e != INVALID; ++e)
    9.20 +  {
    9.21 +    int edgeid = (int)(*(mapstorage->edgemap_storage["id"]))[e];
    9.22 +    m[edgeid] = mapstorage->arrow_pos[e];
    9.23 +  }
    9.24 +  x("arrow_pos", m);
    9.25 +}
    9.26 +
    9.27 +GuiWriter::GuiWriter(LemonWriter& writer, MapStorage* ms) : Parent(writer), mapstorage(ms)
    9.28 +{
    9.29 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/gui/gui_writer.h	Sat Dec 17 20:55:41 2005 +0000
    10.3 @@ -0,0 +1,21 @@
    10.4 +#ifndef GUI_WRITER_H
    10.5 +#define GUI_WRITER_H
    10.6 +
    10.7 +#include "mapstorage.h"
    10.8 +#include <lemon/lemon_writer.h>
    10.9 +
   10.10 +using lemon::LemonWriter;
   10.11 +
   10.12 +class GuiWriter : public LemonWriter::SectionWriter
   10.13 +{
   10.14 +  private:
   10.15 +    MapStorage* mapstorage;
   10.16 +  protected:
   10.17 +    virtual std::string header();
   10.18 +    virtual void write(std::ostream&);
   10.19 +  public:
   10.20 +    typedef LemonWriter::SectionWriter Parent;
   10.21 +    GuiWriter(LemonWriter&, MapStorage*);
   10.22 +};
   10.23 +
   10.24 +#endif
    11.1 --- a/gui/mapstorage.cc	Wed Dec 14 18:11:03 2005 +0000
    11.2 +++ b/gui/mapstorage.cc	Sat Dec 17 20:55:41 2005 +0000
    11.3 @@ -1,16 +1,23 @@
    11.4  #include "mapstorage.h"
    11.5 +#include "gui_writer.h"
    11.6 +#include "gui_reader.h"
    11.7  #include <gtkmm.h>
    11.8  #include <cmath>
    11.9  
   11.10  #include <cmath>
   11.11  
   11.12 -MapStorage::MapStorage() : modified(false), file_name("")
   11.13 +MapStorage::MapStorage() : modified(false), file_name(""), arrow_pos_read_ok(false)
   11.14  {
   11.15    nodemap_storage["coordinates_x"] = new Graph::NodeMap<double>(graph);
   11.16    coords.setXMap(*nodemap_storage["coordinates_x"]);
   11.17    nodemap_storage["coordinates_y"] = new Graph::NodeMap<double>(graph);
   11.18    coords.setYMap(*nodemap_storage["coordinates_y"]);
   11.19  
   11.20 +  edgemap_storage["arrow_pos_x"] = new Graph::EdgeMap<double>(graph);
   11.21 +  arrow_pos.setXMap(*edgemap_storage["arrow_pos_x"]);
   11.22 +  edgemap_storage["arrow_pos_y"] = new Graph::EdgeMap<double>(graph);
   11.23 +  arrow_pos.setYMap(*edgemap_storage["arrow_pos_y"]);
   11.24 +
   11.25    nodemap_storage["id"] = new Graph::NodeMap<double>(graph);
   11.26    edgemap_storage["id"] = new Graph::EdgeMap<double>(graph);
   11.27  
   11.28 @@ -247,6 +254,7 @@
   11.29        }
   11.30        greader.readEdgeMap(*it, *edgemap_storage[*it]);
   11.31      }
   11.32 +    GuiReader gui_reader(greader, this);
   11.33      greader.run();
   11.34    } catch (DataFormatError& error) {
   11.35      Gtk::MessageDialog mdialog(error.what());
   11.36 @@ -283,6 +291,15 @@
   11.37      }
   11.38    }
   11.39  
   11.40 +  if (!arrow_pos_read_ok)
   11.41 +  {
   11.42 +    arrow_pos_read_ok = false;
   11.43 +    for (EdgeIt e(graph); e != INVALID; ++e)
   11.44 +    {
   11.45 +      arrow_pos.set(e, (coords[graph.source(e)] + coords[graph.target(e)]) / 2.0);
   11.46 +    }
   11.47 +  }
   11.48 +
   11.49    // fill in the default values for the maps
   11.50    for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
   11.51        nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
   11.52 @@ -338,14 +355,19 @@
   11.53        nodemap_storage.begin(); it != nodemap_storage.end(); ++it)
   11.54    {
   11.55      gwriter.writeNodeMap(it->first, *(it->second));
   11.56 -    //std::cout << "wrote " << it->first << " nodemap" << std::endl;
   11.57    }
   11.58    for (std::map<std::string, Graph::EdgeMap<double>*>::const_iterator it =
   11.59        edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
   11.60    {
   11.61 -    gwriter.writeEdgeMap(it->first, *(it->second));
   11.62 -    //std::cout << "wrote " << it->first << " edgemap" << std::endl;
   11.63 +    if ((it->first != "arrow_pos_x") &&
   11.64 +        (it->first != "arrow_pos_y"))
   11.65 +    {
   11.66 +      gwriter.writeEdgeMap(it->first, *(it->second));
   11.67 +    }
   11.68    }
   11.69 +
   11.70 +  GuiWriter gui_writer(gwriter, this);
   11.71 +
   11.72    gwriter.run();
   11.73  }
   11.74  
   11.75 @@ -365,7 +387,9 @@
   11.76    for (std::map<std::string, Graph::EdgeMap<double>*>::iterator it =
   11.77        edgemap_storage.begin(); it != edgemap_storage.end(); ++it)
   11.78    {
   11.79 -    if (it->first != "id")
   11.80 +    if ((it->first != "id") &&
   11.81 +        (it->first != "arrow_pos_x") &&
   11.82 +        (it->first != "arrow_pos_y"))
   11.83      {
   11.84        delete it->second;
   11.85        edgemap_storage.erase(it);
   11.86 @@ -387,3 +411,8 @@
   11.87    file_name = "";
   11.88    modified = false;
   11.89  }
   11.90 +
   11.91 +void MapStorage::ArrowPosReadOK()
   11.92 +{
   11.93 +  arrow_pos_read_ok = true;
   11.94 +}
    12.1 --- a/gui/mapstorage.h	Wed Dec 14 18:11:03 2005 +0000
    12.2 +++ b/gui/mapstorage.h	Sat Dec 17 20:55:41 2005 +0000
    12.3 @@ -23,7 +23,10 @@
    12.4  public:
    12.5  
    12.6    Graph graph;
    12.7 +  /// the coordinates of the nodes
    12.8    XYMap<Graph::NodeMap<double> > coords;
    12.9 +  /// the coordinates of the arrows on the edges
   12.10 +  XYMap<Graph::EdgeMap<double> > arrow_pos;
   12.11  
   12.12    bool modified;
   12.13    std::string file_name;
   12.14 @@ -52,6 +55,8 @@
   12.15    // Default values for the maps
   12.16    std::map< std::string, double > edgemap_default;
   12.17  
   12.18 +  bool arrow_pos_read_ok;
   12.19 +
   12.20  protected:
   12.21    typedef sigc::signal<void, bool, int> Signal_Prop;
   12.22    Signal_Prop signal_prop;
   12.23 @@ -127,6 +132,8 @@
   12.24    void writeToFile(const std::string &);
   12.25  
   12.26    void clear();
   12.27 +
   12.28 +  void ArrowPosReadOK();
   12.29  };
   12.30  
   12.31  #endif //MAPSTORAGE_H
    13.1 --- a/gui/xymap.h	Wed Dec 14 18:11:03 2005 +0000
    13.2 +++ b/gui/xymap.h	Sat Dec 17 20:55:41 2005 +0000
    13.3 @@ -4,9 +4,6 @@
    13.4  #include <lemon/list_graph.h>
    13.5  #include <lemon/xy.h>
    13.6  
    13.7 -using lemon::ListGraph;
    13.8 -using lemon::xy;
    13.9 -
   13.10  template<class M>
   13.11  class XYMap
   13.12  {
   13.13 @@ -15,7 +12,7 @@
   13.14  
   13.15    public:
   13.16      typedef typename M::Key Key;
   13.17 -    typedef xy<typename M::Value> Value;
   13.18 +    typedef lemon::xy<typename M::Value> Value;
   13.19      XYMap() {}
   13.20      XYMap(M &_xmap, M &_ymap) : xmap(&_xmap), ymap(&_ymap) {}
   13.21      void setXMap(M &_xmap) { xmap = &_xmap; }