hegyi@1819: #include "graph_displayer_canvas.h"
alpar@1632: #include <cmath>
hegyi@1497: 
ladanyi@1860: GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc) : Line(g), edge(_edge), gdc(gc), isbutton(false)
hegyi@1497: {
hegyi@1499:   arrow=new Gnome::Canvas::Polygon(g);
hegyi@1499:   *arrow << Gnome::Canvas::Properties::fill_color("red");
hegyi@1819:   arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
ladanyi@1645:   arrow->lower_to_bottom();
ladanyi@1860:   draw();
hegyi@1499: }
hegyi@1499: 
hegyi@1819: GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
hegyi@1499: {
hegyi@1499:   if(arrow)delete(arrow);
hegyi@1499: }
hegyi@1499: 
ladanyi@1860: void GraphDisplayerCanvas::BrokenEdge::draw()
hegyi@1499: {
ladanyi@1860:   MapStorage& ms = gdc.mytab.mapstorage;
ladanyi@1860: 
ladanyi@1860:   // update the edge
ladanyi@1860:   {
ladanyi@1860:     Gnome::Canvas::Points points;
ladanyi@1860:     Node source = ms.graph.source(edge);
ladanyi@1860:     Node target = ms.graph.target(edge);
ladanyi@1860:     points.push_back(Gnome::Art::Point(ms.coords[source].x,
ladanyi@1860:           ms.coords[source].y));
ladanyi@1860:     points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
ladanyi@1860:           ms.arrow_pos[edge].y));
ladanyi@1860:     points.push_back(Gnome::Art::Point(ms.coords[target].x,
ladanyi@1860:           ms.coords[target].y));
ladanyi@1860:     property_points().set_value(points);
ladanyi@1860:   }
ladanyi@1860: 
ladanyi@1860:   // update the arrow
ladanyi@1860:   {
ladanyi@1860:     //calculating coordinates of the direction indicator arrow
ladanyi@1860:     XY target(ms.coords[ms.graph.target(edge)]);
ladanyi@1860:     XY center(ms.arrow_pos[edge]);
ladanyi@1860: 
ladanyi@1860:     XY unit_vector_in_dir(target-center);
ladanyi@1860:     double length=sqrt( unit_vector_in_dir.normSquare() );
ladanyi@1860: 
ladanyi@1860:     //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
ladanyi@1860:     unit_vector_in_dir/=length;
ladanyi@1860:     //       std::cout << " = " << unit_vector_in_dir << std::endl;
ladanyi@1860: 
ladanyi@1860:     XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
ladanyi@1860:     //       std::cout << unit_norm_vector << std::endl;
ladanyi@1860: 
ladanyi@1860:     {      
ladanyi@1860:       //       /\       // top
ladanyi@1860:       //      /  \      //
ladanyi@1860:       //      -  -      // c(enter)l(eft), ccl, ccr, cr
ladanyi@1860:       //       ||       //
ladanyi@1860:       //       ||       // b(ottom)l, br
hegyi@1500:     }
hegyi@1601: 
ladanyi@1860:     double size=3;
hegyi@1601: 
ladanyi@1860:     XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
ladanyi@1860:     XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
ladanyi@1860:     XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
ladanyi@1860:     XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
ladanyi@1860:     XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
ladanyi@1860:     XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
ladanyi@1860:     XY top(center + unit_vector_in_dir * 3 * size);
hegyi@1601: 
ladanyi@1860:     //std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
hegyi@1601: 
ladanyi@1860:     Gnome::Canvas::Points arrow_points;
ladanyi@1860:     arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
ladanyi@1860:     arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
ladanyi@1860:     arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
ladanyi@1860:     arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
ladanyi@1860:     arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
ladanyi@1860:     arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
ladanyi@1860:     arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
hegyi@1601: 
ladanyi@1860:     arrow->property_points().set_value(arrow_points);
ladanyi@1860:   }
hegyi@1497: }
hegyi@1499: 
hegyi@1819: bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
hegyi@1499: {
hegyi@1499:   switch(e->type)
hegyi@1499:     {
hegyi@1499:     case GDK_BUTTON_PRESS:
hegyi@1499:       //we mark the location of the event to be able to calculate parameters of dragging
hegyi@1524:       if(gdc.getActualTool()!=CREATE_NODE)
hegyi@1501: 	{
hegyi@1524: 	  gdc.toggleEdgeActivity(this, true);
hegyi@1501: 	  clicked_x=e->button.x;
hegyi@1501: 	  clicked_y=e->button.y;
hegyi@1501: 	  isbutton=true;
hegyi@1501: 	}
hegyi@1499:       break;
hegyi@1499:     case GDK_BUTTON_RELEASE:
hegyi@1524:       if(gdc.getActualTool()!=CREATE_NODE)
hegyi@1505: 	{
hegyi@1524: 	  gdc.toggleEdgeActivity(this, false);
hegyi@1505: 	  isbutton=false;
hegyi@1505: 	}
hegyi@1499:       break;
hegyi@1499:     case GDK_MOTION_NOTIFY:
hegyi@1499:       //we only have to do sg. if the mouse button is pressed
hegyi@1499:       if(isbutton)
hegyi@1499: 	{
hegyi@1499: 	  //new coordinates will be the old values,
hegyi@1499: 	  //because the item will be moved to the
hegyi@1499: 	  //new coordinate therefore the new movement
hegyi@1499: 	  //has to be calculated from here
hegyi@1499: 
hegyi@1499: 	  double dx=e->motion.x-clicked_x;
hegyi@1499: 	  double dy=e->motion.y-clicked_y;
hegyi@1499: 
hegyi@1499: 	  Gnome::Canvas::Points points_new;
hegyi@1499: 
ladanyi@1860:           gdc.mytab.mapstorage.arrow_pos.set(edge, gdc.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
hegyi@1499: 
ladanyi@1860: 	  draw();
ladanyi@1860: 	  gdc.textReposition(gdc.mytab.mapstorage.arrow_pos[edge]);
hegyi@1499: 
hegyi@1499: 	  clicked_x=e->motion.x;
hegyi@1499: 	  clicked_y=e->motion.y;
hegyi@1499: 
hegyi@1499: 	}
hegyi@1499:     default: break;
hegyi@1499:     }
hegyi@1499: 
hegyi@1499:   return true;
hegyi@1499: }