3 |
3 |
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),target_item(NULL) |
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),target_item(NULL) |
5 { |
5 { |
6 |
6 |
7 actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false); |
7 actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false); |
|
8 |
|
9 active_node=INVALID; |
|
10 active_edge=INVALID; |
8 |
11 |
9 //set_center_scroll_region(true); |
12 //set_center_scroll_region(true); |
10 |
13 |
11 //first edges are drawn, to hide joining with nodes later |
14 //first edges are drawn, to hide joining with nodes later |
12 |
15 |
455 bool GraphDisplayerCanvas::create_edge_event_handler(GdkEvent* e) |
469 bool GraphDisplayerCanvas::create_edge_event_handler(GdkEvent* e) |
456 { |
470 { |
457 switch(e->type) |
471 switch(e->type) |
458 { |
472 { |
459 case GDK_BUTTON_PRESS: |
473 case GDK_BUTTON_PRESS: |
460 if(!active_item) |
474 //in edge creatino right button has special meaning |
|
475 if(e->button.button!=3) |
461 { |
476 { |
462 //we mark the location of the event to be able to calculate parameters of dragging |
477 //there is not yet selected node |
463 clicked_x=e->button.x; |
478 if(active_node==INVALID) |
464 clicked_y=e->button.y; |
|
465 active_item=(get_item_at(e->button.x, e->button.y)); |
|
466 active_node=INVALID; |
|
467 for (NodeIt i(g); i!=INVALID; ++i) |
|
468 { |
479 { |
469 if(nodesmap[i]==active_item) |
480 //we mark the location of the event to be able to calculate parameters of dragging |
|
481 clicked_x=e->button.x; |
|
482 clicked_y=e->button.y; |
|
483 active_item=(get_item_at(e->button.x, e->button.y)); |
|
484 active_node=INVALID; |
|
485 for (NodeIt i(g); i!=INVALID; ++i) |
470 { |
486 { |
471 active_node=i; |
487 if(nodesmap[i]==active_item) |
|
488 { |
|
489 active_node=i; |
|
490 } |
|
491 } |
|
492 //the clicked item is really a node |
|
493 if(active_node!=INVALID) |
|
494 { |
|
495 *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); |
|
496 isbutton=true; |
|
497 } |
|
498 //clicked item was not a node. It could be e.g. edge. |
|
499 else |
|
500 { |
|
501 active_item=NULL; |
472 } |
502 } |
473 } |
503 } |
474 *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); |
504 //we only have to do sg. if the mouse button |
475 isbutton=true; |
505 // is pressed already once AND the click was |
476 } |
506 // on a node that was found in the set of |
477 else |
507 //nodes, and now we only search for the second |
478 { |
508 //node |
479 target_item=(get_item_at(e->button.x, e->button.y)); |
509 else |
480 Graph::NodeIt target_node=INVALID; |
|
481 for (NodeIt i(g); i!=INVALID; ++i) |
|
482 { |
510 { |
483 if(nodesmap[i]==target_item) |
511 target_item=(get_item_at(e->button.x, e->button.y)); |
|
512 Graph::NodeIt target_node=INVALID; |
|
513 for (NodeIt i(g); i!=INVALID; ++i) |
484 { |
514 { |
485 target_node=i; |
515 if(nodesmap[i]==target_item) |
|
516 { |
|
517 target_node=i; |
|
518 } |
|
519 } |
|
520 //the clicked item is a node, the edge can be drawn |
|
521 if(target_node!=INVALID) |
|
522 { |
|
523 *(nodesmap[target_node]) << Gnome::Canvas::Properties::fill_color("red"); |
|
524 |
|
525 //creating new edge |
|
526 active_edge=EdgeIt(g,g.addEdge(active_node, target_node)); |
|
527 |
|
528 //calculating coordinates of new edge |
|
529 Gnome::Canvas::Points coos; |
|
530 double x1, x2, y1, y2; |
|
531 |
|
532 active_item->get_bounds(x1, y1, x2, y2); |
|
533 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
|
534 |
|
535 target_item->get_bounds(x1, y1, x2, y2); |
|
536 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
|
537 |
|
538 //drawing new edge |
|
539 edgesmap[active_edge]=new Gnome::Canvas::Line(displayed_graph, coos); |
|
540 *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green"); |
|
541 edgesmap[active_edge]->property_width_pixels().set_value(10); |
|
542 |
|
543 //redraw nodes to blank terminations of the new edge |
|
544 target_item->raise_to_top(); |
|
545 active_item->raise_to_top(); |
|
546 |
|
547 //initializing edge-text as well, to empty string |
|
548 edgesmap[active_edge]->get_bounds(x1, y1, x2, y2); |
|
549 edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, ""); |
|
550 edgetextmap[active_edge]->property_fill_color().set_value("black"); |
|
551 } |
|
552 //clicked item was not a node. it could be an e.g. edge. we do not deal with it furthermore. |
|
553 else |
|
554 { |
|
555 target_item=NULL; |
486 } |
556 } |
487 } |
557 } |
488 *(nodesmap[target_node]) << Gnome::Canvas::Properties::fill_color("red"); |
|
489 |
|
490 //creating new edge |
|
491 // Graph::Edge new_edge=g.addEdge(active_node, target_node); |
|
492 active_edge=EdgeIt(g,g.addEdge(active_node, target_node)); |
|
493 |
|
494 //calculating coordinates of new edge |
|
495 Gnome::Canvas::Points coos; |
|
496 double x1, x2, y1, y2; |
|
497 |
|
498 active_item->get_bounds(x1, y1, x2, y2); |
|
499 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
|
500 |
|
501 target_item->get_bounds(x1, y1, x2, y2); |
|
502 coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); |
|
503 |
|
504 //drawing new edge |
|
505 edgesmap[active_edge]=new Gnome::Canvas::Line(displayed_graph, coos); |
|
506 *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green"); |
|
507 edgesmap[active_edge]->property_width_pixels().set_value(10); |
|
508 |
|
509 //redraw nodes to blank terminations of the new edge |
|
510 target_item->raise_to_top(); |
|
511 active_item->raise_to_top(); |
|
512 |
|
513 //initializing edge-text as well, to empty string |
|
514 edgesmap[active_edge]->get_bounds(x1, y1, x2, y2); |
|
515 edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, ""); |
|
516 edgetextmap[active_edge]->property_fill_color().set_value("black"); |
|
517 } |
558 } |
518 break; |
559 break; |
519 case GDK_BUTTON_RELEASE: |
560 case GDK_BUTTON_RELEASE: |
520 isbutton=false; |
561 isbutton=false; |
521 if(target_item) |
562 //we clear settings in two cases |
|
563 //1: the edge is ready (target_item has valid value) |
|
564 //2: the edge creation is cancelled with right button |
|
565 if((target_item)||(e->button.button==3)) |
522 { |
566 { |
523 *active_item << Gnome::Canvas::Properties::fill_color("blue"); |
567 if(active_item) |
524 *target_item << Gnome::Canvas::Properties::fill_color("blue"); |
568 { |
525 active_item=NULL; |
569 *active_item << Gnome::Canvas::Properties::fill_color("blue"); |
526 target_item=NULL; |
570 active_item=NULL; |
|
571 } |
|
572 if(target_item) |
|
573 { |
|
574 *target_item << Gnome::Canvas::Properties::fill_color("blue"); |
|
575 target_item=NULL; |
|
576 } |
|
577 active_node=INVALID; |
|
578 active_edge=INVALID; |
527 } |
579 } |
528 break; |
580 break; |
529 default: |
581 default: |
530 break; |
582 break; |
531 } |
583 } |