graph_displayer_canvas.cc
branchgui
changeset 12 1db7a6dd17f8
parent 11 09b2a893fc9d
child 13 0b2281cc1e32
equal deleted inserted replaced
6:1730e9e4ab99 7:b920ceb8e1a8
     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 
   308   switch(newtool)
   311   switch(newtool)
   309     {
   312     {
   310     case MOVE:
   313     case MOVE:
   311       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::move_event_handler), false);
   314       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::move_event_handler), false);
   312       break;
   315       break;
       
   316 
       
   317       //it has to assigned to canvas, because all the canvas has to be monitored, not only the elements of the already drawn group
   313     case CREATE_NODE:
   318     case CREATE_NODE:
   314       actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_node_event_handler), false);
   319       actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_node_event_handler), false);
   315       break;
   320       break;
       
   321 
   316     case CREATE_EDGE:
   322     case CREATE_EDGE:
   317       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false);
   323       actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false);
   318       break;
   324       break;
   319     default:
   325     default:
   320       break;
   326       break;
   341       isbutton=true;
   347       isbutton=true;
   342       break;
   348       break;
   343     case GDK_BUTTON_RELEASE:
   349     case GDK_BUTTON_RELEASE:
   344       isbutton=false;
   350       isbutton=false;
   345       active_item=NULL;
   351       active_item=NULL;
       
   352       active_node=INVALID;
   346       updateScrollRegion();
   353       updateScrollRegion();
   347       break;
   354       break;
   348     case GDK_MOTION_NOTIFY:
   355     case GDK_MOTION_NOTIFY:
   349       //we only have to do sg. if the mouse button is pressed
   356       //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
   350       if(isbutton)
   357       if(active_node!=INVALID)
   351       {
   358       {
   352 	//new coordinates will be the old values,
   359 	//new coordinates will be the old values,
   353 	//because the item will be moved to the
   360 	//because the item will be moved to the
   354 	//new coordinate therefore the new movement
   361 	//new coordinate therefore the new movement
   355 	//has to be calculated from here
   362 	//has to be calculated from here
   414 
   421 
   415 bool GraphDisplayerCanvas::create_node_event_handler(GdkEvent* e)
   422 bool GraphDisplayerCanvas::create_node_event_handler(GdkEvent* e)
   416 {
   423 {
   417   switch(e->type)
   424   switch(e->type)
   418     {
   425     {
       
   426 
       
   427       //draw the new node in red at the clicked place
   419     case GDK_BUTTON_PRESS:
   428     case GDK_BUTTON_PRESS:
   420       isbutton=true;
   429       isbutton=true;
   421 
   430 
   422       active_node=NodeIt(g,g.addNode());
   431       active_node=NodeIt(g,g.addNode());
   423 
   432 
   427       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
   436       active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
   428       *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
   437       *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
   429       *(nodesmap[active_node]) << Gnome::Canvas::Properties::outline_color("black");
   438       *(nodesmap[active_node]) << Gnome::Canvas::Properties::outline_color("black");
   430       (nodesmap[active_node])->show();
   439       (nodesmap[active_node])->show();
   431       break;
   440       break;
       
   441 
       
   442       //move the new node
   432     case GDK_MOTION_NOTIFY:
   443     case GDK_MOTION_NOTIFY:
   433       {
   444       {
   434 	double world_motion_x, world_motion_y;
   445 	double world_motion_x, world_motion_y;
   435 	GdkEvent * generated=new GdkEvent();
   446 	GdkEvent * generated=new GdkEvent();
   436 	window_to_world (e->motion.x, e->motion.y, world_motion_x, world_motion_y);
   447 	window_to_world (e->motion.x, e->motion.y, world_motion_x, world_motion_y);
   438 	generated->motion.y=world_motion_y;
   449 	generated->motion.y=world_motion_y;
   439 	generated->type=GDK_MOTION_NOTIFY;
   450 	generated->type=GDK_MOTION_NOTIFY;
   440 	move_event_handler(generated);      
   451 	move_event_handler(generated);      
   441 	break;
   452 	break;
   442       }
   453       }
       
   454 
       
   455       //finalize the new node
   443     case GDK_BUTTON_RELEASE:
   456     case GDK_BUTTON_RELEASE:
   444       isbutton=false;
   457       isbutton=false;
   445       *active_item << Gnome::Canvas::Properties::fill_color("blue");
   458       *active_item << Gnome::Canvas::Properties::fill_color("blue");
   446       active_item=NULL;
   459       active_item=NULL;
       
   460       active_node=INVALID;
   447       updateScrollRegion();
   461       updateScrollRegion();
   448       break;
   462       break;
   449     default:
   463     default:
   450       break;
   464       break;
   451     }
   465     }
   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     }