Node antigravity and edge elasticity based graph layout redesigner.
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