Node antigravity and edge elasticity based graph layout redesigner.
authorhegyi
Thu, 12 Oct 2006 11:39:29 +0000
changeset 16014a76109b561
parent 159 7ea73c90a7f0
child 161 aef1fbfd9d60
Node antigravity and edge elasticity based graph layout redesigner.
Makefile.am
graph_displayer_canvas-event.cc
graph_displayer_canvas.cc
graph_displayer_canvas.h
main_win.cc
main_win.h
nbtab.cc
nbtab.h
     1.1 --- a/Makefile.am	Mon Oct 09 08:06:31 2006 +0000
     1.2 +++ b/Makefile.am	Thu Oct 12 11:39:29 2006 +0000
     1.3 @@ -42,7 +42,9 @@
     1.4  	xml.h \
     1.5  	guipixbufs.h \
     1.6  	i18n.h \
     1.7 -	gettext.h
     1.8 +	gettext.h \
     1.9 +	design_win.h \
    1.10 +	design_win.cc
    1.11  
    1.12  glemon_CXXFLAGS = $(GTK_CFLAGS) $(LEMON_CFLAGS)
    1.13  glemon_LDFLAGS = $(GTK_LIBS) $(LEMON_LIBS)
     2.1 --- a/graph_displayer_canvas-event.cc	Mon Oct 09 08:06:31 2006 +0000
     2.2 +++ b/graph_displayer_canvas-event.cc	Thu Oct 12 11:39:29 2006 +0000
     2.3 @@ -81,11 +81,11 @@
     2.4  {
     2.5    static Gnome::Canvas::Text *coord_text = 0;
     2.6    switch(e->type)
     2.7 -  {
     2.8 +    {
     2.9      case GDK_BUTTON_PRESS:
    2.10        //we mark the location of the event to be able to calculate parameters of dragging
    2.11        window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
    2.12 -
    2.13 +      
    2.14        active_item=(get_item_at(clicked_x, clicked_y));
    2.15        active_node=INVALID;
    2.16        for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
    2.17 @@ -99,10 +99,10 @@
    2.18        break;
    2.19      case GDK_BUTTON_RELEASE:
    2.20        if (coord_text)
    2.21 -      {
    2.22 -        delete coord_text;
    2.23 -        coord_text = 0;
    2.24 -      }
    2.25 +	{
    2.26 +	  delete coord_text;
    2.27 +	  coord_text = 0;
    2.28 +	}
    2.29        isbutton=0;
    2.30        active_item=NULL;
    2.31        active_node=INVALID;
    2.32 @@ -110,122 +110,59 @@
    2.33      case GDK_MOTION_NOTIFY:
    2.34        //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
    2.35        if(active_node!=INVALID)
    2.36 -      {
    2.37 -        (mytab.mapstorage).modified = true;
    2.38 +	{
    2.39 +	  (mytab.mapstorage).modified = true;
    2.40 +	  
    2.41 +	  //new coordinates will be the old values,
    2.42 +	  //because the item will be moved to the
    2.43 +	  //new coordinate therefore the new movement
    2.44 +	  //has to be calculated from here
    2.45 +	  
    2.46 +	  double new_x, new_y;
    2.47 +	  
    2.48 +	  window_to_world (e->motion.x, e->motion.y, new_x, new_y);
    2.49 +	  
    2.50 +	  double dx=new_x-clicked_x;
    2.51 +	  double dy=new_y-clicked_y;
    2.52 +	  
    2.53 +	  moveNode(dx, dy);
    2.54  
    2.55 -	//new coordinates will be the old values,
    2.56 -	//because the item will be moved to the
    2.57 -	//new coordinate therefore the new movement
    2.58 -	//has to be calculated from here
    2.59 +	  clicked_x=new_x;
    2.60 +	  clicked_y=new_y;
    2.61  
    2.62 -	double new_x, new_y;
    2.63 +	  // reposition the coordinates text
    2.64 +	  std::ostringstream ostr;
    2.65 +	  ostr << "(" <<
    2.66 +	    (mytab.mapstorage).coords[active_node].x << ", " <<
    2.67 +	    (mytab.mapstorage).coords[active_node].y << ")";
    2.68 +	  double radius =
    2.69 +	    (nodesmap[active_node]->property_x2().get_value() -
    2.70 +	     nodesmap[active_node]->property_x1().get_value()) / 2.0;
    2.71 +	  if (coord_text)
    2.72 +	    {
    2.73 +	      coord_text->property_text().set_value(ostr.str());
    2.74 +	      coord_text->property_x().set_value((mytab.mapstorage).coords[active_node].x +
    2.75 +						 radius);
    2.76 +	      coord_text->property_y().set_value((mytab.mapstorage).coords[active_node].y -
    2.77 +						 radius);
    2.78 +	    }
    2.79 +	  else
    2.80 +	    {
    2.81 +	      coord_text = new Gnome::Canvas::Text(
    2.82 +						   displayed_graph,
    2.83 +						   (mytab.mapstorage).coords[active_node].x + radius,
    2.84 +						   (mytab.mapstorage).coords[active_node].y - radius,
    2.85 +						   ostr.str());
    2.86 +	      coord_text->property_fill_color().set_value("black");
    2.87 +	      coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST);
    2.88 +	    }
    2.89  
    2.90 -	window_to_world (e->motion.x, e->motion.y, new_x, new_y);
    2.91  
    2.92 -        double dx=new_x-clicked_x;
    2.93 -        double dy=new_y-clicked_y;
    2.94 +	}
    2.95 +    default: break;
    2.96 +    }
    2.97  
    2.98 -	//repositioning node and its text
    2.99 -        active_item->move(dx, dy);
   2.100 -	nodetextmap[active_node]->move(dx, dy);
   2.101 -
   2.102 -        // the new coordinates of the centre of the node 
   2.103 -        double coord_x = new_x - (clicked_x - (mytab.mapstorage).coords[active_node].x);
   2.104 -        double coord_y = new_y - (clicked_y - (mytab.mapstorage).coords[active_node].y);
   2.105 -
   2.106 -        // write back the new coordinates to the coords map
   2.107 -        (mytab.mapstorage).coords.set(active_node, XY(coord_x, coord_y));
   2.108 -
   2.109 -        clicked_x=new_x;
   2.110 -        clicked_y=new_y;
   2.111 -
   2.112 -        // reposition the coordinates text
   2.113 -        std::ostringstream ostr;
   2.114 -        ostr << "(" <<
   2.115 -          (mytab.mapstorage).coords[active_node].x << ", " <<
   2.116 -          (mytab.mapstorage).coords[active_node].y << ")";
   2.117 -        double radius =
   2.118 -          (nodesmap[active_node]->property_x2().get_value() -
   2.119 -          nodesmap[active_node]->property_x1().get_value()) / 2.0;
   2.120 -        if (coord_text)
   2.121 -        {
   2.122 -          coord_text->property_text().set_value(ostr.str());
   2.123 -          coord_text->property_x().set_value((mytab.mapstorage).coords[active_node].x +
   2.124 -              radius);
   2.125 -          coord_text->property_y().set_value((mytab.mapstorage).coords[active_node].y -
   2.126 -              radius);
   2.127 -        }
   2.128 -        else
   2.129 -        {
   2.130 -          coord_text = new Gnome::Canvas::Text(
   2.131 -              displayed_graph,
   2.132 -              (mytab.mapstorage).coords[active_node].x + radius,
   2.133 -              (mytab.mapstorage).coords[active_node].y - radius,
   2.134 -              ostr.str());
   2.135 -          coord_text->property_fill_color().set_value("black");
   2.136 -          coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST);
   2.137 -        }
   2.138 -
   2.139 -	//all the edges connected to the moved point has to be redrawn
   2.140 -        for(OutEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
   2.141 -        {
   2.142 -          XY arrow_pos;
   2.143 -
   2.144 -          if (mytab.mapstorage.graph.source(ei) == mytab.mapstorage.graph.target(ei))
   2.145 -          {
   2.146 -            arrow_pos = mytab.mapstorage.arrow_pos[ei] + XY(dx, dy);
   2.147 -          }
   2.148 -          else
   2.149 -          {
   2.150 -            XY moved_node_1(coord_x - dx, coord_y - dy);
   2.151 -            XY moved_node_2(coord_x, coord_y);
   2.152 -            Node target = mytab.mapstorage.graph.target(ei);
   2.153 -            XY fix_node(mytab.mapstorage.coords[target].x,
   2.154 -                mytab.mapstorage.coords[target].y);
   2.155 -            XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
   2.156 -
   2.157 -            arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
   2.158 -          }
   2.159 -
   2.160 -          mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
   2.161 -          edgesmap[ei]->draw();
   2.162 -
   2.163 -          //reposition of edgetext
   2.164 -          XY text_pos=mytab.mapstorage.arrow_pos[ei];
   2.165 -          text_pos+=(XY(10,10));
   2.166 -          edgetextmap[ei]->property_x().set_value(text_pos.x);
   2.167 -          edgetextmap[ei]->property_y().set_value(text_pos.y);
   2.168 -        }
   2.169 -
   2.170 -        for(InEdgeIt ei((mytab.mapstorage).graph,active_node);ei!=INVALID;++ei)
   2.171 -        {
   2.172 -          if (mytab.mapstorage.graph.source(ei) != mytab.mapstorage.graph.target(ei))
   2.173 -          {
   2.174 -            XY moved_node_1(coord_x - dx, coord_y - dy);
   2.175 -            XY moved_node_2(coord_x, coord_y);
   2.176 -            Node source = mytab.mapstorage.graph.source(ei);
   2.177 -            XY fix_node(mytab.mapstorage.coords[source].x,
   2.178 -                mytab.mapstorage.coords[source].y);
   2.179 -            XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
   2.180 -
   2.181 -            XY arrow_pos;
   2.182 -            arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
   2.183 -
   2.184 -            mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
   2.185 -            edgesmap[ei]->draw();
   2.186 -
   2.187 -            //reposition of edgetext
   2.188 -            XY text_pos=mytab.mapstorage.arrow_pos[ei];
   2.189 -            text_pos+=(XY(10,10));
   2.190 -            edgetextmap[ei]->property_x().set_value(text_pos.x);
   2.191 -            edgetextmap[ei]->property_y().set_value(text_pos.y);
   2.192 -          }
   2.193 -        }
   2.194 -      }
   2.195 -    default: break;
   2.196 -  }
   2.197 -
   2.198 -  return false;
   2.199 +return false;
   2.200  }
   2.201  
   2.202  XY GraphDisplayerCanvas::calcArrowPos(XY moved_node_1, XY moved_node_2, XY fix_node, XY old_arrow_pos, int move_code)
   2.203 @@ -823,14 +760,97 @@
   2.204      }
   2.205    }
   2.206    else
   2.207 -  {
   2.208 -    if(forming_edge!=INVALID)
   2.209      {
   2.210 -      forming_edge=INVALID;
   2.211 +      if(forming_edge!=INVALID)
   2.212 +	{
   2.213 +	  forming_edge=INVALID;
   2.214 +	}
   2.215 +      else
   2.216 +	{
   2.217 +	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   2.218 +	}
   2.219      }
   2.220 -    else
   2.221 +}
   2.222 +
   2.223 +void GraphDisplayerCanvas::moveNode(double dx, double dy, Gnome::Canvas::Item * item, Node node)
   2.224 +{
   2.225 +  Gnome::Canvas::Item * moved_item=item;
   2.226 +  Node moved_node=node;
   2.227 +
   2.228 +  if(item==NULL && node==INVALID)
   2.229      {
   2.230 -      std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
   2.231 +      moved_item=active_item;
   2.232 +      moved_node=active_node;
   2.233      }
   2.234 -  }
   2.235 +  else
   2.236 +    {
   2.237 +      isbutton=1;
   2.238 +    }
   2.239 +
   2.240 +  //repositioning node and its text
   2.241 +  moved_item->move(dx, dy);
   2.242 +  nodetextmap[moved_node]->move(dx, dy);
   2.243 +
   2.244 +  // the new coordinates of the centre of the node 
   2.245 +  double coord_x = dx + (mytab.mapstorage).coords[moved_node].x;
   2.246 +  double coord_y = dy + (mytab.mapstorage).coords[moved_node].y;
   2.247 +
   2.248 +  // write back the new coordinates to the coords map
   2.249 +  (mytab.mapstorage).coords.set(moved_node, XY(coord_x, coord_y));
   2.250 +
   2.251 +  //all the edges connected to the moved point has to be redrawn
   2.252 +  for(OutEdgeIt ei((mytab.mapstorage).graph,moved_node);ei!=INVALID;++ei)
   2.253 +    {
   2.254 +      XY arrow_pos;
   2.255 +
   2.256 +      if (mytab.mapstorage.graph.source(ei) == mytab.mapstorage.graph.target(ei))
   2.257 +	{
   2.258 +	  arrow_pos = mytab.mapstorage.arrow_pos[ei] + XY(dx, dy);
   2.259 +	}
   2.260 +      else
   2.261 +	{
   2.262 +	  XY moved_node_1(coord_x - dx, coord_y - dy);
   2.263 +	  XY moved_node_2(coord_x, coord_y);
   2.264 +	  Node target = mytab.mapstorage.graph.target(ei);
   2.265 +	  XY fix_node(mytab.mapstorage.coords[target].x,
   2.266 +		      mytab.mapstorage.coords[target].y);
   2.267 +	  XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
   2.268 +
   2.269 +	  arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
   2.270 +	}
   2.271 +
   2.272 +      mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
   2.273 +      edgesmap[ei]->draw();
   2.274 +
   2.275 +      //reposition of edgetext
   2.276 +      XY text_pos=mytab.mapstorage.arrow_pos[ei];
   2.277 +      text_pos+=(XY(10,10));
   2.278 +      edgetextmap[ei]->property_x().set_value(text_pos.x);
   2.279 +      edgetextmap[ei]->property_y().set_value(text_pos.y);
   2.280 +    }
   2.281 +
   2.282 +  for(InEdgeIt ei((mytab.mapstorage).graph,moved_node);ei!=INVALID;++ei)
   2.283 +    {
   2.284 +      if (mytab.mapstorage.graph.source(ei) != mytab.mapstorage.graph.target(ei))
   2.285 +	{
   2.286 +	  XY moved_node_1(coord_x - dx, coord_y - dy);
   2.287 +	  XY moved_node_2(coord_x, coord_y);
   2.288 +	  Node source = mytab.mapstorage.graph.source(ei);
   2.289 +	  XY fix_node(mytab.mapstorage.coords[source].x,
   2.290 +		      mytab.mapstorage.coords[source].y);
   2.291 +	  XY old_arrow_pos(mytab.mapstorage.arrow_pos[ei]);
   2.292 +
   2.293 +	  XY arrow_pos;
   2.294 +	  arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
   2.295 +
   2.296 +	  mytab.mapstorage.arrow_pos.set(ei, arrow_pos);
   2.297 +	  edgesmap[ei]->draw();
   2.298 +
   2.299 +	  //reposition of edgetext
   2.300 +	  XY text_pos=mytab.mapstorage.arrow_pos[ei];
   2.301 +	  text_pos+=(XY(10,10));
   2.302 +	  edgetextmap[ei]->property_x().set_value(text_pos.x);
   2.303 +	  edgetextmap[ei]->property_y().set_value(text_pos.y);
   2.304 +	}
   2.305 +    }
   2.306  }
     3.1 --- a/graph_displayer_canvas.cc	Mon Oct 09 08:06:31 2006 +0000
     3.2 +++ b/graph_displayer_canvas.cc	Thu Oct 12 11:39:29 2006 +0000
     3.3 @@ -5,7 +5,8 @@
     3.4    nodesmap(mainw.mapstorage.graph), edgesmap(mainw.mapstorage.graph), edgetextmap(mainw.mapstorage.graph),
     3.5    nodetextmap(mainw.mapstorage.graph), displayed_graph(*(root()), 0, 0),
     3.6    isbutton(0), active_item(NULL), target_item(NULL), nodemap_to_edit(""),
     3.7 -  edgemap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), edge_width(10), mytab(mainw)
     3.8 +  edgemap_to_edit(""), autoscale(true), zoomtrack(false), radius_size(20), edge_width(10),
     3.9 +  iterations(20), attraction(0.05), propulsation(40000), mytab(mainw)
    3.10  {
    3.11    //base event handler is move tool
    3.12    actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
    3.13 @@ -251,3 +252,117 @@
    3.14    width_p=edge_width;
    3.15    radius_p=radius_size;
    3.16  }
    3.17 +
    3.18 +void GraphDisplayerCanvas::reDesignGraph()
    3.19 +{
    3.20 +  double min_dist=40;
    3.21 +
    3.22 +  //iteration counter
    3.23 +  for(int l=0;l<iterations;l++)
    3.24 +    {
    3.25 +      Graph::NodeMap<double> x(mytab.mapstorage.graph);
    3.26 +      Graph::NodeMap<double> y(mytab.mapstorage.graph);
    3.27 +      XYMap<Graph::NodeMap<double> > actual_forces;
    3.28 +      actual_forces.setXMap(x);
    3.29 +      actual_forces.setYMap(y);
    3.30 +
    3.31 +      lemon::dim2::Point<double> delta;
    3.32 +
    3.33 +      //count actual force for each nodes
    3.34 +      for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
    3.35 +	{
    3.36 +	  //propulsation of nodes
    3.37 +	  for (NodeIt j((mytab.mapstorage).graph); j!=INVALID; ++j)
    3.38 +	    {
    3.39 +	      if(i!=j)
    3.40 +		{
    3.41 +		  delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[j]);
    3.42 +
    3.43 +		  double length_sqr=delta.normSquare();
    3.44 +		  double length=sqrt(length_sqr);
    3.45 +		  if(length_sqr<min_dist)
    3.46 +		    {
    3.47 +		      length_sqr=min_dist;
    3.48 +		    }
    3.49 +
    3.50 +		  //normalize vector
    3.51 +		  delta/=length;
    3.52 +
    3.53 +		  //calculating propulsation strength
    3.54 +		  //greater distance menas smaller propulsation strength
    3.55 +		  delta*=propulsation/length_sqr;
    3.56 +		    
    3.57 +		  actual_forces.set(i,(actual_forces[i]+delta));
    3.58 +		}
    3.59 +	    }
    3.60 +	  //attraction of nodes, to which actual node is bound
    3.61 +	  for(OutEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
    3.62 +	    {
    3.63 +	      delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[mytab.mapstorage.graph.target(ei)]);
    3.64 +
    3.65 +	      double length_sqr=delta.normSquare();
    3.66 +	      double length=sqrt(length_sqr);
    3.67 +	      if(length_sqr<min_dist)
    3.68 +		{
    3.69 +		  length_sqr=min_dist;
    3.70 +		}
    3.71 +
    3.72 +	      //normalize vector
    3.73 +	      delta/=length;
    3.74 +
    3.75 +	      //calculating attraction strength
    3.76 +	      //greater distance means greater strength
    3.77 +	      delta*=attraction*length;
    3.78 +
    3.79 +	      actual_forces.set(i,actual_forces[i]-delta);
    3.80 +	    }
    3.81 +	  for(InEdgeIt ei((mytab.mapstorage).graph,i);ei!=INVALID;++ei)
    3.82 +	    {
    3.83 +	      delta=((mytab.mapstorage).coords[i]-(mytab.mapstorage).coords[mytab.mapstorage.graph.source(ei)]);
    3.84 +
    3.85 +	      double length_sqr=delta.normSquare();
    3.86 +	      double length=sqrt(length_sqr);
    3.87 +	      if(length_sqr<min_dist)
    3.88 +		{
    3.89 +		  length_sqr=min_dist;
    3.90 +		}
    3.91 +
    3.92 +	      //normalize vector
    3.93 +	      delta/=length;
    3.94 +
    3.95 +	      //calculating attraction strength
    3.96 +	      //greater distance means greater strength
    3.97 +	      delta*=attraction*length;
    3.98 +
    3.99 +	      actual_forces.set(i,actual_forces[i]-delta);
   3.100 +	    }
   3.101 +	}
   3.102 +      for (NodeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
   3.103 +	{
   3.104 +	  moveNode(actual_forces[i].x, actual_forces[i].y, nodesmap[i], i);
   3.105 +	}
   3.106 +    }
   3.107 +}
   3.108 +
   3.109 +void GraphDisplayerCanvas::get_design_data(double & attraction_p, double & propulsation_p, int & iterations_p)
   3.110 +{
   3.111 +  attraction_p=attraction;
   3.112 +  propulsation_p=propulsation;
   3.113 +  iterations_p=iterations;
   3.114 +}
   3.115 +
   3.116 +void GraphDisplayerCanvas::set_attraction(double attraction_p)
   3.117 +{
   3.118 +  attraction=attraction_p;
   3.119 +}
   3.120 +
   3.121 +void GraphDisplayerCanvas::set_propulsation(double propulsation_p)
   3.122 +{
   3.123 +  propulsation=propulsation_p;
   3.124 +}
   3.125 +
   3.126 +void GraphDisplayerCanvas::set_iteration(int iterations_p)
   3.127 +{
   3.128 +  iterations=iterations_p;
   3.129 +}
   3.130 +
     4.1 --- a/graph_displayer_canvas.h	Mon Oct 09 08:06:31 2006 +0000
     4.2 +++ b/graph_displayer_canvas.h	Thu Oct 12 11:39:29 2006 +0000
     4.3 @@ -268,6 +268,10 @@
     4.4    ///event handler for the case when map editor tool is active
     4.5    bool mapEditEventHandler(GdkEvent*);
     4.6  
     4.7 +private:
     4.8 +  ///moves node according to the given parameters
     4.9 +  void moveNode(double, double,  Gnome::Canvas::Item * item=NULL, Node node=INVALID);
    4.10 +
    4.11  public:
    4.12    ///Moves the text to new place
    4.13    void textReposition(XY);
    4.14 @@ -314,6 +318,13 @@
    4.15    ///\param mapname name of new map
    4.16    int addNewEdgeMap(double init,std::string mapname);
    4.17  
    4.18 +  void reDesignGraph();
    4.19 +
    4.20 +  void get_design_data(double &, double &, int &);
    4.21 +  void set_attraction(double);
    4.22 +  void set_propulsation(double);
    4.23 +  void set_iteration(int);
    4.24 +
    4.25  private:
    4.26    ///Deletes the given element.
    4.27    void deleteItem(Node);
    4.28 @@ -398,6 +409,15 @@
    4.29    ///Edge width
    4.30    double edge_width;
    4.31  
    4.32 +  ///Iteration number during graph design
    4.33 +  int iterations;
    4.34 +
    4.35 +  ///Attraction factor during graph design
    4.36 +  double attraction;
    4.37 +
    4.38 +  ///Propulsation factor during graph design
    4.39 +  double propulsation;
    4.40 +  
    4.41  private:
    4.42  
    4.43    ///reference to the container, in which the canvas is
     5.1 --- a/main_win.cc	Mon Oct 09 08:06:31 2006 +0000
     5.2 +++ b/main_win.cc	Thu Oct 12 11:39:29 2006 +0000
     5.3 @@ -99,6 +99,8 @@
     5.4    ag->add( Gtk::Action::create("ShowMenu", _("_Show")) );
     5.5    ag->add( Gtk::Action::create("ShowMaps", _("_Maps")),
     5.6  	   sigc::mem_fun(*this, &MainWin::createMapWin));
     5.7 +  ag->add( Gtk::Action::create("ShowDesign", _("_Design")),
     5.8 +	   sigc::mem_fun(*this, &MainWin::createDesignWin));
     5.9  
    5.10    ag->add( Gtk::Action::create("AlgoMenu", _("_Algorithms")) );
    5.11    ag->add( Gtk::Action::create("AlgoGeneral", _("_General")),
    5.12 @@ -122,6 +124,9 @@
    5.13    ag->add( Gtk::Action::create("AddMap", Gtk::StockID("gd-newmap")),
    5.14        sigc::mem_fun ( *this , &MainWin::createNewMapWin ) );
    5.15  
    5.16 +  ag->add( Gtk::Action::create("DesignGraph", Gtk::Stock::REFRESH),
    5.17 +      sigc::mem_fun ( *this , &MainWin::reDesignGraph ) );
    5.18 +
    5.19    uim=Gtk::UIManager::create();
    5.20    uim->insert_action_group(ag);
    5.21    add_accel_group(uim->get_accel_group());
    5.22 @@ -149,6 +154,7 @@
    5.23        "    </menu>"
    5.24        "    <menu action='ShowMenu'>"
    5.25        "      <menuitem action='ShowMaps'/>"
    5.26 +      "      <menuitem action='ShowDesign'/>"
    5.27        "    </menu>"
    5.28        "    <menu action='AlgoMenu'>"
    5.29        "      <menuitem action='AlgoGeneral'/>"
    5.30 @@ -173,6 +179,7 @@
    5.31        "    <toolitem action='EditEdgeMap' />"
    5.32        "    <separator />"
    5.33        "    <toolitem action='AddMap' />"
    5.34 +      "    <toolitem action='DesignGraph' />"
    5.35        "  </toolbar>"
    5.36        "</ui>";
    5.37  
    5.38 @@ -448,6 +455,14 @@
    5.39      }
    5.40  }
    5.41  
    5.42 +void MainWin::createDesignWin()
    5.43 +{
    5.44 +  if(active_tab!=-1)
    5.45 +    {
    5.46 +      tabs[active_tab]->createDesignWin(tabnames[active_tab]);
    5.47 +    }
    5.48 +}
    5.49 +
    5.50  void MainWin::createAlgoWin(int algoid)
    5.51  {
    5.52    AlgoWin * aw=new AlgoWin(algoid, tabnames);
    5.53 @@ -536,3 +551,8 @@
    5.54    bool autoscale=auto_scale->get_active();
    5.55    tabs[active_tab]->setView(autoscale, zoomtrack, width, radius);
    5.56  }
    5.57 +
    5.58 +void MainWin::reDesignGraph()
    5.59 +{
    5.60 +  tabs[active_tab]->reDesignGraph();
    5.61 +}
     6.1 --- a/main_win.h	Mon Oct 09 08:06:31 2006 +0000
     6.2 +++ b/main_win.h	Thu Oct 12 11:39:29 2006 +0000
     6.3 @@ -145,6 +145,12 @@
     6.4    ///\ref NoteBookTab
     6.5    virtual void createMapWin();
     6.6  
     6.7 +  ///Callback for Show Design menupoint.
     6.8 +
     6.9 +  ///It calls the appropriate function in
    6.10 +  ///\ref NoteBookTab
    6.11 +  virtual void createDesignWin();
    6.12 +
    6.13    ///Pops up an Algorithm window.
    6.14  
    6.15    ///It not only creates but registrates the newly created \ref AlgoWin.
    6.16 @@ -237,6 +243,8 @@
    6.17    virtual void onChangeTab(GtkNotebookPage*, guint);
    6.18  
    6.19    virtual void nodeViewChanged();
    6.20 +
    6.21 +  virtual void reDesignGraph();
    6.22  };
    6.23  
    6.24  #endif //MAIN_WIN_H
     7.1 --- a/nbtab.cc	Mon Oct 09 08:06:31 2006 +0000
     7.2 +++ b/nbtab.cc	Thu Oct 12 11:39:29 2006 +0000
     7.3 @@ -1,6 +1,6 @@
     7.4  #include <nbtab.h>
     7.5  
     7.6 -NoteBookTab::NoteBookTab():mapwinexists(false)
     7.7 +NoteBookTab::NoteBookTab():mapwinexists(false), designwinexists(false)
     7.8  {
     7.9    Gtk::ScrolledWindow *pScrolledWindow = manage(new Gtk::ScrolledWindow);
    7.10    gd_canvas=new GraphDisplayerCanvas(*this);
    7.11 @@ -207,12 +207,42 @@
    7.12      }
    7.13  }
    7.14  
    7.15 +void NoteBookTab::createDesignWin(std::string name)
    7.16 +{
    7.17 +  if(!designwinexists)
    7.18 +    {
    7.19 +      double attraction, propulsation;
    7.20 +      int iterations;
    7.21 +      gd_canvas->get_design_data(attraction, propulsation, iterations);
    7.22 +      designwin=new DesignWin("Design Setup - "+name, attraction, propulsation, iterations);
    7.23 +
    7.24 +      designwin->signal_attraction().connect(sigc::mem_fun(*this, &NoteBookTab::attraction_ch));
    7.25 +      designwin->signal_propulsation().connect(sigc::mem_fun(*this, &NoteBookTab::propulsation_ch));
    7.26 +      designwin->signal_iteration().connect(sigc::mem_fun(*gd_canvas, &GraphDisplayerCanvas::set_iteration));
    7.27 +      designwin->close_run().connect(sigc::mem_fun(*gd_canvas, &GraphDisplayerCanvas::reDesignGraph));
    7.28 +
    7.29 +      designwin->signal_delete_event().connect(sigc::mem_fun(*this, &NoteBookTab::closeDesignWin));
    7.30 +
    7.31 +      designwin->show();
    7.32 +      designwinexists=true;
    7.33 +    }
    7.34 +}
    7.35 +
    7.36  void NoteBookTab::closeMapWin()
    7.37  {
    7.38    mapwinexists=false;
    7.39    delete mapwin;
    7.40  }
    7.41  
    7.42 +bool NoteBookTab::closeDesignWin(GdkEventAny * e)
    7.43 +{
    7.44 +  if(e->type==GDK_DELETE)
    7.45 +    {
    7.46 +      designwinexists=false;
    7.47 +      delete designwin;
    7.48 +    }
    7.49 +}
    7.50 +
    7.51  sigc::signal<void, std::string> NoteBookTab::signal_title_ch()
    7.52  {
    7.53    return signal_title;
    7.54 @@ -227,3 +257,24 @@
    7.55  {
    7.56    gd_canvas->getView(autoscale, zoomtrack, width, radius);
    7.57  }
    7.58 +
    7.59 +void NoteBookTab::reDesignGraph()
    7.60 +{
    7.61 +  gd_canvas->reDesignGraph();
    7.62 +}
    7.63 +
    7.64 +void NoteBookTab::attraction_ch(double v)
    7.65 +{
    7.66 +  gd_canvas->set_attraction(v);
    7.67 +}
    7.68 +
    7.69 +void NoteBookTab::propulsation_ch(double v)
    7.70 +{
    7.71 +  gd_canvas->set_propulsation(v);
    7.72 +}
    7.73 +
    7.74 +void NoteBookTab::iteration_ch(int v)
    7.75 +{
    7.76 +  gd_canvas->set_iteration(v);
    7.77 +}
    7.78 +
     8.1 --- a/nbtab.h	Mon Oct 09 08:06:31 2006 +0000
     8.2 +++ b/nbtab.h	Thu Oct 12 11:39:29 2006 +0000
     8.3 @@ -7,6 +7,7 @@
     8.4  
     8.5  #include "mapstorage.h"
     8.6  #include "map_win.h"
     8.7 +#include "design_win.h"
     8.8  #include "graph_displayer_canvas.h"
     8.9  #include <libgnomecanvasmm.h>
    8.10  #include <libgnomecanvasmm/polygon.h>
    8.11 @@ -77,6 +78,9 @@
    8.12    ///Indicates whether the \ref MapWin is opened or not. See \ref mapwin.
    8.13    bool mapwinexists;
    8.14  
    8.15 +  ///Indicates whether the \ref DesignWin is opened or not. See \ref designwin.
    8.16 +  bool designwinexists;
    8.17 +
    8.18    ///Address of the only \ref MapWin that the \ref NoteBookTab can open.
    8.19  
    8.20    ///Only one of this window can be opened at the same time (\ref mapwinexists), 
    8.21 @@ -85,6 +89,14 @@
    8.22    ///more complicated to synchronize them.
    8.23    MapWin * mapwin;
    8.24      
    8.25 +  ///Address of the only \ref DesignWin that the \ref NoteBookTab can open.
    8.26 +
    8.27 +  ///Only one of this window can be opened at the same time (\ref designwinexists), 
    8.28 +  ///because there is no need for more, one per tab is enough.
    8.29 +  ///There won't be benefit of more than one, but it would be
    8.30 +  ///more complicated to synchronize them.
    8.31 +  DesignWin * designwin;
    8.32 +
    8.33  public:
    8.34    ///Callback for 'FileNew' action.
    8.35    virtual void newFile();
    8.36 @@ -151,17 +163,33 @@
    8.37    ///\ref mapwin.
    8.38    void createMapWin(std::string);
    8.39  
    8.40 +  ///Pops up and registrates the \ref DesignWin of \ref NoteBookTab.
    8.41 +  
    8.42 +  ///See also
    8.43 +  ///\ref mapwin.
    8.44 +  void createDesignWin(std::string);
    8.45 +
    8.46    ///Closes and deregistrates the \ref MapWin of \ref NoteBookTab.
    8.47    
    8.48    ///See also
    8.49    ///\ref mapwin.
    8.50    void closeMapWin();
    8.51  
    8.52 +  bool closeDesignWin(GdkEventAny *);
    8.53 +
    8.54    ///Sets node representation settings
    8.55    void setView(bool, bool, double, double);
    8.56  
    8.57    ///Gets node representation settings
    8.58    void getView(bool &, bool &, double&, double&);
    8.59 +
    8.60 +  void reDesignGraph();
    8.61 +
    8.62 +  void attraction_ch(double);
    8.63 +
    8.64 +  void propulsation_ch(double);
    8.65 +
    8.66 +  void iteration_ch(int);
    8.67  };
    8.68  
    8.69  #endif //NBTAB_H