Some tests have been developed, bugs got fixed.
1 #include <graph_displayer_canvas.h>
4 GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & gr, CoordinatesMap & cm, MapStorage & ms):g(gr),nodesmap(g),edgesmap(g),edgetextmap(g),displayed_graph(*(root()), 0, 0),mapstorage(ms),isbutton(false),active_item(NULL)
6 Gnome::Canvas::Ellipse * origo=new Gnome::Canvas::Ellipse(displayed_graph, 0-20, 0-20, 0+20, 0+20);
7 *origo << Gnome::Canvas::Properties::fill_color("black");
8 *origo << Gnome::Canvas::Properties::outline_color("black");
10 actual_handler=/*displayed_graph.*/signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_node_event_handler), false);
12 //set_center_scroll_region(true);
14 //first edges are drawn, to hide joining with nodes later
16 for (EdgeIt i(g); i!=INVALID; ++i)
19 //drawing green lines, coordinates are from cm
21 Gnome::Canvas::Points coos;
22 coos.push_back(Gnome::Art::Point(cm[g.source(i)].x,cm[g.source(i)].y));
23 coos.push_back(Gnome::Art::Point(cm[g.target(i)].x,cm[g.target(i)].y));
25 edgesmap[i]=new Gnome::Canvas::Line(displayed_graph, coos);
26 *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");
27 edgesmap[i]->property_width_pixels().set_value(10);
29 //initializing edge-text as well, to empty string
31 double x1, x2, y1, y2;
32 edgesmap[i]->get_bounds(x1, y1, x2, y2);
34 edgetextmap[i]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, "");
35 edgetextmap[i]->property_fill_color().set_value("black");
38 //afterwards nodes come to be drawn
41 int maxx=0, maxy=0, minx=(int)cm[i].x, miny=(int)cm[i].y;
43 for (; i!=INVALID; ++i)
45 //minimum and maximum is gathered to be able to zoom to the graph correctly (whole figure should be seen)
47 if(cm[i].x>maxx)maxx=(int)cm[i].x;
48 if(cm[i].y>maxy)maxy=(int)cm[i].y;
49 if(cm[i].x<minx)minx=(int)cm[i].x;
50 if(cm[i].y<miny)miny=(int)cm[i].y;
52 //drawing bule nodes, with black line around them
54 nodesmap[i]=new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
55 *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
56 *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
57 //!!!!!!! (nodesmap[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),i));
63 GraphDisplayerCanvas::~GraphDisplayerCanvas()
66 //writing out the end state of the graph
67 //\todo all the maps has to be write out!
69 Graph::NodeMap <int> id(g);
70 Graph::NodeMap <double> xc(g);
71 Graph::NodeMap <double> yc(g);
75 for (NodeIt i(g); i!=INVALID; ++i)
78 nodesmap[i]->get_bounds(x1, y1, x2, y2);
85 GraphWriter<Graph> writer(std::cout,g);
87 writer.writeNodeMap("id", id);
88 writer.writeNodeMap("coordinates_x", xc);
89 writer.writeNodeMap("coordinates_y", yc);
93 int GraphDisplayerCanvas::changeLineWidth (std::string mapname)
95 for (EdgeIt i(g); i!=INVALID; ++i)
97 int w=(int)(*(mapstorage.edgemap_storage)[mapname])[i];
98 edgesmap[i]->property_width_pixels().set_value(w);
103 int GraphDisplayerCanvas::changeColor (std::string mapname)
106 //function maps the range of the maximum and
107 //the minimum of the nodemap to the range of
110 for (EdgeIt i(g); i!=INVALID; ++i)
112 double w=(*(mapstorage.edgemap_storage)[mapname])[i];
113 double max=mapstorage.maxOfEdgeMap(mapname);
114 double min=mapstorage.minOfEdgeMap(mapname);
116 //std::cout<<w<<" "<<max<<" "<<min<<" "<<100*(w-min)/(max-min)<<std::endl;
120 color.set_rgb_p (0, 100*(w-min)/(max-min), 0);
124 color.set_rgb_p (0, 100, 0);
127 edgesmap[i]->property_fill_color_gdk().set_value(color);
132 int GraphDisplayerCanvas::changeText (std::string mapname)
135 //the number in the map will be written on the edge
136 //EXCEPT when the name of the map is Text, because
137 //in that case empty string will be written, because
138 //that is the deleter map
139 //\todo isn't it a bit woodcutter?
141 for (EdgeIt i(g); i!=INVALID; ++i)
145 double number=(*(mapstorage.edgemap_storage)[mapname])[i];
146 int length=(int)(floor(log(number)/log(10)))+1;
147 int maxpos=(int)(pow(10,length-1));
148 int strl=length+1+RANGE;
149 char * str=new char[strl];
153 for(int j=0;j<strl;j++)
157 int digit=(int)(number/maxpos);
159 number-=digit*maxpos;
164 edgetextmap[i]->property_text().set_value(str);
168 edgetextmap[i]->property_text().set_value("");
174 bool GraphDisplayerCanvas::event_handler(GdkEvent* e, Node n)
178 case GDK_BUTTON_PRESS:
179 //we mark the location of the event to be able to calculate parameters of dragging
180 clicked_x=e->button.x;
181 clicked_y=e->button.y;
182 active_item=(get_item_at(e->button.x, e->button.y));
185 case GDK_BUTTON_RELEASE:
188 updateScrollRegion();
190 case GDK_MOTION_NOTIFY:
191 //we only have to do sg. if the mouse button is pressed
194 //new coordinates will be the old values,
195 //because the item will be moved to the
196 //new coordinate therefore the new movement
197 //has to be calculated from here
199 double dx=e->motion.x-clicked_x;
200 double dy=e->motion.y-clicked_y;
201 active_item->move(dx, dy);
202 clicked_x=e->motion.x;
203 clicked_y=e->motion.y;
205 //all the edges connected to the moved point has to be redrawn
209 for(;e!=INVALID;g.nextOut(e))
211 Gnome::Canvas::Points coos;
212 double x1, x2, y1, y2;
214 nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
215 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
217 nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
218 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
220 edgesmap[e]->property_points().set_value(coos);
222 edgesmap[e]->get_bounds(x1, y1, x2, y2);
224 edgetextmap[e]->property_x().set_value((x1+x2)/2);
225 edgetextmap[e]->property_y().set_value((y1+y2)/2);
229 for(;e!=INVALID;g.nextIn(e))
231 Gnome::Canvas::Points coos;
232 double x1, x2, y1, y2;
234 nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
235 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
237 nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
238 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
240 edgesmap[e]->property_points().set_value(coos);
242 edgesmap[e]->get_bounds(x1, y1, x2, y2);
244 edgetextmap[e]->property_x().set_value((x1+x2)/2);
245 edgetextmap[e]->property_y().set_value((y1+y2)/2);
253 bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
255 Gnome::Canvas::CanvasAA::on_expose_event(event);
261 void GraphDisplayerCanvas::zoomIn()
264 (1.0 + (double) zoom_step / 100.0) * get_pixels_per_unit());
267 void GraphDisplayerCanvas::zoomOut()
270 (1.0 - (double) zoom_step / 100.0) * get_pixels_per_unit());
273 void GraphDisplayerCanvas::zoomFit()
275 // get the height and width of the canvas
276 Gtk::Allocation a = get_allocation();
277 int aw = a.get_width();
278 int ah = a.get_height();
280 aw -= 5; if (aw < 0) aw = 0;
281 ah -= 5; if (ah < 0) ah = 0;
283 // get the bounding box of the graph
284 double wx1, wy1, wx2, wy2;
285 Gnome::Canvas::Item* pCanvasItem = root();
286 pCanvasItem->get_bounds(wx1, wy1, wx2, wy2);
288 // fit the graph to the window
289 double ppu1 = (double) aw / fabs(wx2 - wx1);
290 double ppu2 = (double) ah / fabs(wy2 - wy1);
291 set_pixels_per_unit((ppu1 < ppu2) ? ppu1 : ppu2);
294 void GraphDisplayerCanvas::zoom100()
296 set_pixels_per_unit(1.0);
299 void GraphDisplayerCanvas::updateScrollRegion()
301 double wx1, wy1, wx2, wy2;
302 Gnome::Canvas::Item* pCanvasItem = root();
303 pCanvasItem->get_bounds(wx1, wy1, wx2, wy2);
304 set_scroll_region(wx1, wy1, wx2, wy2);
307 void GraphDisplayerCanvas::changeEditorialTool(int newtool)
309 actual_handler.disconnect();
314 actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::move_event_handler), false);
317 actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_node_event_handler), false);
320 actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false);
327 bool GraphDisplayerCanvas::move_event_handler(GdkEvent* e)
331 case GDK_BUTTON_PRESS:
332 //we mark the location of the event to be able to calculate parameters of dragging
333 clicked_x=e->button.x;
334 clicked_y=e->button.y;
335 active_item=(get_item_at(e->button.x, e->button.y));
337 for (NodeIt i(g); i!=INVALID; ++i)
339 if(nodesmap[i]==active_item)
346 case GDK_BUTTON_RELEASE:
349 updateScrollRegion();
351 case GDK_MOTION_NOTIFY:
352 //we only have to do sg. if the mouse button is pressed
355 //new coordinates will be the old values,
356 //because the item will be moved to the
357 //new coordinate therefore the new movement
358 //has to be calculated from here
360 double dx=e->motion.x-clicked_x;
361 double dy=e->motion.y-clicked_y;
363 active_item->move(dx, dy);
365 clicked_x=e->motion.x;
366 clicked_y=e->motion.y;
368 //all the edges connected to the moved point has to be redrawn
372 g.firstOut(e,active_node);
374 for(;e!=INVALID;g.nextOut(e))
376 Gnome::Canvas::Points coos;
377 double x1, x2, y1, y2;
379 nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
380 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
382 nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
383 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
385 edgesmap[e]->property_points().set_value(coos);
387 edgesmap[e]->get_bounds(x1, y1, x2, y2);
389 edgetextmap[e]->property_x().set_value((x1+x2)/2);
390 edgetextmap[e]->property_y().set_value((y1+y2)/2);
393 g.firstIn(e,active_node);
394 for(;e!=INVALID;g.nextIn(e))
396 Gnome::Canvas::Points coos;
397 double x1, x2, y1, y2;
399 nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
400 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
402 nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
403 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
405 edgesmap[e]->property_points().set_value(coos);
407 edgesmap[e]->get_bounds(x1, y1, x2, y2);
409 edgetextmap[e]->property_x().set_value((x1+x2)/2);
410 edgetextmap[e]->property_y().set_value((y1+y2)/2);
419 bool GraphDisplayerCanvas::create_node_event_handler(GdkEvent* e)
423 case GDK_BUTTON_PRESS:
426 active_node=NodeIt(g,g.addNode());
428 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
430 nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph, clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
431 active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
432 *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
433 *(nodesmap[active_node]) << Gnome::Canvas::Properties::outline_color("black");
434 (nodesmap[active_node])->show();
436 case GDK_MOTION_NOTIFY:
438 double world_motion_x, world_motion_y;
439 GdkEvent * generated=new GdkEvent();
440 window_to_world (e->motion.x, e->motion.y, world_motion_x, world_motion_y);
441 generated->motion.x=world_motion_x;
442 generated->motion.y=world_motion_y;
443 generated->type=GDK_MOTION_NOTIFY;
444 move_event_handler(generated);
447 case GDK_BUTTON_RELEASE:
449 *active_item << Gnome::Canvas::Properties::fill_color("blue");
451 updateScrollRegion();
459 bool GraphDisplayerCanvas::create_edge_event_handler(GdkEvent* e)