212 } |
212 } |
213 |
213 |
214 bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e) |
214 bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e) |
215 { |
215 { |
216 switch(e->type) |
216 switch(e->type) |
217 { |
217 { |
218 |
218 //move the new node |
219 //draw the new node in red at the clicked place |
219 case GDK_MOTION_NOTIFY: |
220 case GDK_2BUTTON_PRESS: |
220 { |
221 //std::cout << "double click" << std::endl; |
221 GdkEvent * generated=new GdkEvent(); |
222 break; |
222 generated->motion.x=e->motion.x; |
223 case GDK_BUTTON_PRESS: |
223 generated->motion.y=e->motion.y; |
|
224 generated->type=GDK_MOTION_NOTIFY; |
|
225 moveEventHandler(generated); |
|
226 break; |
|
227 } |
|
228 |
|
229 case GDK_BUTTON_RELEASE: |
224 mapstorage.modified = true; |
230 mapstorage.modified = true; |
225 |
231 |
226 isbutton=1; |
232 isbutton=1; |
227 |
233 |
228 active_node=mapstorage.graph.addNode(); |
234 active_node=mapstorage.graph.addNode(); |
229 |
235 |
230 //initiating values corresponding to new node in maps |
236 //initiating values corresponding to new node in maps |
231 |
237 |
232 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); |
238 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); |
233 |
239 |
|
240 // update coordinates |
234 mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y)); |
241 mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y)); |
|
242 |
|
243 // update id map |
235 (*mapstorage.nodemap_storage["id"])[active_node] = |
244 (*mapstorage.nodemap_storage["id"])[active_node] = |
236 mapstorage.graph.id(active_node); |
245 mapstorage.graph.id(active_node); |
237 |
246 |
|
247 // update all other maps |
|
248 for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it = |
|
249 mapstorage.nodemap_storage.begin(); it != |
|
250 mapstorage.nodemap_storage.end(); ++it) |
|
251 { |
|
252 if ((it->first != "id") && |
|
253 (it->first != "coordinates_x") && |
|
254 (it->first != "coordiantes_y")) |
|
255 { |
|
256 (*(it->second))[active_node] = |
|
257 mapstorage.nodemap_default[it->first]; |
|
258 } |
|
259 } |
|
260 |
238 nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph, |
261 nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph, |
239 clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20); |
262 clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20); |
240 active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]); |
263 active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]); |
241 *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); |
264 *(nodesmap[active_node]) << |
242 *(nodesmap[active_node]) << Gnome::Canvas::Properties::outline_color("black"); |
265 Gnome::Canvas::Properties::fill_color("blue"); |
|
266 *(nodesmap[active_node]) << |
|
267 Gnome::Canvas::Properties::outline_color("black"); |
|
268 active_item->raise_to_top(); |
|
269 |
243 (nodesmap[active_node])->show(); |
270 (nodesmap[active_node])->show(); |
244 |
271 |
245 nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph, |
272 nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph, |
246 clicked_x+node_property_defaults[N_RADIUS]+5, |
273 clicked_x+node_property_defaults[N_RADIUS]+5, |
247 clicked_y+node_property_defaults[N_RADIUS]+5, ""); |
274 clicked_y+node_property_defaults[N_RADIUS]+5, ""); |
248 nodetextmap[active_node]->property_fill_color().set_value("darkblue"); |
275 nodetextmap[active_node]->property_fill_color().set_value("darkblue"); |
|
276 nodetextmap[active_node]->raise_to_top(); |
249 |
277 |
250 mapwin.updateNode(active_node); |
278 mapwin.updateNode(active_node); |
251 |
279 |
252 break; |
|
253 |
|
254 //move the new node |
|
255 case GDK_MOTION_NOTIFY: |
|
256 { |
|
257 GdkEvent * generated=new GdkEvent(); |
|
258 generated->motion.x=e->motion.x; |
|
259 generated->motion.y=e->motion.y; |
|
260 generated->type=GDK_MOTION_NOTIFY; |
|
261 moveEventHandler(generated); |
|
262 break; |
|
263 } |
|
264 |
|
265 //finalize the new node |
|
266 case GDK_BUTTON_RELEASE: |
|
267 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); |
|
268 |
|
269 active_item->lower_to_bottom(); |
|
270 |
|
271 target_item=NULL; |
|
272 target_item=get_item_at(clicked_x, clicked_y); |
|
273 |
|
274 active_item->raise_to_top(); |
|
275 |
|
276 isbutton=0; |
280 isbutton=0; |
277 if(target_item==active_item) |
|
278 { |
|
279 //Its appropriate color is given by update. |
|
280 *active_item << Gnome::Canvas::Properties::fill_color("blue"); |
|
281 } |
|
282 else |
|
283 { |
|
284 //In this case the given color has to be overwritten, because the noe covers an other item. |
|
285 *active_item << Gnome::Canvas::Properties::fill_color("lightblue"); |
|
286 } |
|
287 target_item=NULL; |
281 target_item=NULL; |
288 active_item=NULL; |
282 active_item=NULL; |
289 active_node=INVALID; |
283 active_node=INVALID; |
|
284 |
290 break; |
285 break; |
291 default: |
286 default: |
292 break; |
287 break; |
293 } |
288 } |
294 return false; |
289 return false; |
295 } |
290 } |
296 |
291 |
297 bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e) |
292 bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e) |
298 { |
293 { |
299 switch(e->type) |
294 switch(e->type) |
300 { |
295 { |
301 case GDK_BUTTON_PRESS: |
296 case GDK_BUTTON_PRESS: |
302 //in edge creation right button has special meaning |
297 //in edge creation right button has special meaning |
303 if(e->button.button!=3) |
298 if(e->button.button!=3) |
304 { |
299 { |
305 //there is not yet selected node |
300 //there is not yet selected node |
306 if(active_node==INVALID) |
301 if(active_node==INVALID) |
307 { |
302 { |
308 //we mark the location of the event to be able to calculate parameters of dragging |
303 //we mark the location of the event to be able to calculate parameters of dragging |
309 |
304 |
310 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); |
305 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); |
311 |
306 |
312 active_item=(get_item_at(clicked_x, clicked_y)); |
307 active_item=(get_item_at(clicked_x, clicked_y)); |
313 active_node=INVALID; |
308 active_node=INVALID; |
314 for (NodeIt i(mapstorage.graph); i!=INVALID; ++i) |
309 for (NodeIt i(mapstorage.graph); i!=INVALID; ++i) |
315 { |
310 { |
316 if(nodesmap[i]==active_item) |
311 if(nodesmap[i]==active_item) |
317 { |
312 { |
318 active_node=i; |
313 active_node=i; |
319 } |
314 } |
320 } |
315 } |
321 //the clicked item is really a node |
316 //the clicked item is really a node |
322 if(active_node!=INVALID) |
317 if(active_node!=INVALID) |
323 { |
318 { |
324 *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); |
319 *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); |
325 isbutton=1; |
320 isbutton=1; |
326 } |
321 } |
327 //clicked item was not a node. It could be e.g. edge. |
322 //clicked item was not a node. It could be e.g. edge. |
328 else |
323 else |
329 { |
324 { |
330 active_item=NULL; |
325 active_item=NULL; |
331 } |
326 } |
332 } |
327 } |
333 //we only have to do sg. if the mouse button |
328 //we only have to do sg. if the mouse button |
334 // is pressed already once AND the click was |
329 // is pressed already once AND the click was |
335 // on a node that was found in the set of |
330 // on a node that was found in the set of |
336 //nodes, and now we only search for the second |
331 //nodes, and now we only search for the second |
337 //node |
332 //node |
338 else |
333 else |
339 { |
334 { |
340 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); |
335 window_to_world (e->button.x, e->button.y, clicked_x, clicked_y); |
341 target_item=(get_item_at(clicked_x, clicked_y)); |
336 target_item=(get_item_at(clicked_x, clicked_y)); |
342 Node target_node=INVALID; |
337 Node target_node=INVALID; |
343 for (NodeIt i(mapstorage.graph); i!=INVALID; ++i) |
338 for (NodeIt i(mapstorage.graph); i!=INVALID; ++i) |
344 { |
339 { |
345 if(nodesmap[i]==target_item) |
340 if(nodesmap[i]==target_item) |
346 { |
341 { |
347 target_node=i; |
342 target_node=i; |
348 } |
343 } |
349 } |
344 } |
350 //the clicked item is a node, the edge can be drawn |
345 //the clicked item is a node, the edge can be drawn |
351 if(target_node!=INVALID) |
346 if(target_node!=INVALID) |
352 { |
347 { |
353 if(target_node!=active_node) |
348 if(target_node!=active_node) |
354 { |
349 { |
355 mapstorage.modified = true; |
350 mapstorage.modified = true; |
356 |
351 |
357 *(nodesmap[target_node]) << |
352 *(nodesmap[target_node]) << |
358 Gnome::Canvas::Properties::fill_color("red"); |
353 Gnome::Canvas::Properties::fill_color("red"); |
359 |
354 |
360 //creating new edge |
355 //creating new edge |
361 active_edge=mapstorage.graph.addEdge(active_node, |
356 active_edge=mapstorage.graph.addEdge(active_node, |
362 target_node); |
357 target_node); |
363 |
358 |
364 //initiating values corresponding to new edge in maps |
359 // update id map |
365 mapstorage.initMapsForEdge(active_edge); |
360 (*mapstorage.edgemap_storage["id"])[active_edge] = |
366 (*mapstorage.edgemap_storage["id"])[active_edge] = |
361 mapstorage.graph.id(active_edge); |
367 mapstorage.graph.id(active_edge); |
362 |
368 |
363 // update all other maps |
369 //calculating coordinates of new edge |
364 for (std::map<std::string, |
370 Gnome::Canvas::Points coos; |
365 Graph::EdgeMap<double>*>::const_iterator it = |
371 double x1, x2, y1, y2; |
366 mapstorage.edgemap_storage.begin(); it != |
372 |
367 mapstorage.edgemap_storage.end(); ++it) |
373 active_item->get_bounds(x1, y1, x2, y2); |
368 { |
374 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
369 if (it->first != "id") |
375 |
370 { |
376 target_item->get_bounds(x1, y1, x2, y2); |
371 (*(it->second))[active_edge] = |
377 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
372 mapstorage.edgemap_default[it->first]; |
378 |
373 } |
379 //drawing new edge |
374 } |
380 edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos, *this); |
375 |
381 *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green"); |
376 //calculating coordinates of new edge |
382 edgesmap[active_edge]->property_width_pixels().set_value(10); |
377 Gnome::Canvas::Points coos; |
383 |
378 double x1, x2, y1, y2; |
384 //redraw nodes to blank terminations of the new edge |
379 |
385 target_item->raise_to_top(); |
380 active_item->get_bounds(x1, y1, x2, y2); |
386 active_item->raise_to_top(); |
381 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
387 |
382 |
388 //initializing edge-text as well, to empty string |
383 target_item->get_bounds(x1, y1, x2, y2); |
389 xy<double> text_pos=edgesmap[active_edge]->getArrowPos(); |
384 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
390 text_pos+=(xy<double>(10,10)); |
385 |
391 |
386 //drawing new edge |
392 edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph, text_pos.x, text_pos.y, ""); |
387 edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos, |
393 edgetextmap[active_edge]->property_fill_color().set_value("darkgreen"); |
388 *this); |
394 |
389 *(edgesmap[active_edge]) << |
395 //updating its properties |
390 Gnome::Canvas::Properties::fill_color("green"); |
396 mapwin.updateEdge(active_edge); |
391 edgesmap[active_edge]->property_width_pixels().set_value(10); |
397 } |
392 |
398 else |
393 edgesmap[active_edge]->lower_to_bottom(); |
399 { |
394 |
400 target_node=INVALID; |
395 //initializing edge-text as well, to empty string |
401 std::cerr << "Loop edge is not yet implemented!" << std::endl; |
396 xy<double> text_pos=edgesmap[active_edge]->getArrowPos(); |
402 } |
397 text_pos+=(xy<double>(10,10)); |
403 } |
398 |
404 //clicked item was not a node. it could be an e.g. edge. we do not deal with it furthermore. |
399 edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph, |
405 else |
400 text_pos.x, text_pos.y, ""); |
406 { |
401 edgetextmap[active_edge]->property_fill_color().set_value( |
407 target_item=NULL; |
402 "darkgreen"); |
408 } |
403 edgetextmap[active_edge]->raise_to_top(); |
409 } |
404 |
410 } |
405 //updating its properties |
|
406 mapwin.updateEdge(active_edge); |
|
407 } |
|
408 else |
|
409 { |
|
410 target_node=INVALID; |
|
411 std::cerr << "Loop edge is not yet implemented!" << std::endl; |
|
412 } |
|
413 } |
|
414 //clicked item was not a node. it could be an e.g. edge. we do not |
|
415 //deal with it furthermore. |
|
416 else |
|
417 { |
|
418 target_item=NULL; |
|
419 } |
|
420 } |
|
421 } |
411 break; |
422 break; |
412 case GDK_BUTTON_RELEASE: |
423 case GDK_BUTTON_RELEASE: |
413 isbutton=0; |
424 isbutton=0; |
414 //we clear settings in two cases |
425 //we clear settings in two cases |
415 //1: the edge is ready (target_item has valid value) |
426 //1: the edge is ready (target_item has valid value) |
416 //2: the edge creation is cancelled with right button |
427 //2: the edge creation is cancelled with right button |
417 if((target_item)||(e->button.button==3)) |
428 if((target_item)||(e->button.button==3)) |
418 { |
429 { |
419 if(active_item) |
430 if(active_item) |
420 { |
431 { |
421 *active_item << Gnome::Canvas::Properties::fill_color("blue"); |
432 *active_item << Gnome::Canvas::Properties::fill_color("blue"); |
422 active_item=NULL; |
433 active_item=NULL; |
423 } |
434 } |
424 if(target_item) |
435 if(target_item) |
425 { |
436 { |
426 *target_item << Gnome::Canvas::Properties::fill_color("blue"); |
437 *target_item << Gnome::Canvas::Properties::fill_color("blue"); |
427 target_item=NULL; |
438 target_item=NULL; |
428 } |
439 } |
429 active_node=INVALID; |
440 active_node=INVALID; |
430 active_edge=INVALID; |
441 active_edge=INVALID; |
431 } |
442 } |
432 break; |
443 break; |
433 default: |
444 default: |
434 break; |
445 break; |
435 } |
446 } |
436 return false; |
447 return false; |
437 } |
448 } |
438 |
449 |
439 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e) |
450 bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e) |
440 { |
451 { |