broken_edge.cc
author hegyi
Thu, 16 Jun 2005 18:58:15 +0000
branchgui
changeset 20 a3bd39d50930
parent 19 164783ceb9be
child 21 44bb92014108
permissions -rw-r--r--
First of all: revision 1981 is mine, what is important me because I was born in 1981. But what is new in my revision? If you drag nodes with left button, edge-breakpoints do not change location. If you drag nodes by right button, they do, they take up their base situation at the halfpoint of the edge.
     1 #include <broken_edge.h>
     2 #include <lemon/xy.h>
     3 #include <math.h>
     4 
     5 BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Gnome::Canvas::Points p) : Line(g), isbutton(false)
     6 {
     7   my_points=new Gnome::Art::Point[3];
     8 
     9   arrow=new Gnome::Canvas::Polygon(g);
    10   *arrow << Gnome::Canvas::Properties::fill_color("red");
    11   arrow->signal_event().connect(sigc::mem_fun(*this, &BrokenEdge::edge_former_event_handler));
    12   set_points(p);
    13 }
    14 
    15 BrokenEdge::~BrokenEdge()
    16 {
    17   if(arrow)delete(arrow);
    18 }
    19 
    20 void BrokenEdge::set_points(Gnome::Canvas::Points p, bool move)
    21 {
    22   bool set_arrow=false;
    23   if(!move)
    24     {
    25       if(p.size()==2)
    26 	{
    27 	  set_arrow=true;
    28 	  Gnome::Canvas::Points points_with_center;
    29 	  points_with_center.push_back(my_points[0]=p[0]);
    30 	  points_with_center.push_back(my_points[1]=Gnome::Art::Point( (p[0].get_x()+p[1].get_x())/2+0 , (p[0].get_y()+p[1].get_y())/2 )+0 );
    31 	  points_with_center.push_back(my_points[2]=p[1]);
    32 	  property_points().set_value(points_with_center);
    33 	}  
    34       if(p.size()==3)
    35 	{
    36 	  set_arrow=true;
    37 	  property_points().set_value(p);
    38 	  for(int i=0;i<3;i++)
    39 	    {
    40 	      my_points[i]=p[i];
    41 	    }
    42 	}
    43     }
    44   else
    45     {
    46       if(p.size()==2)
    47 	{
    48 	  Gnome::Canvas::Points points;
    49 	  my_points[0]=p[0];
    50 	  my_points[2]=p[1];
    51 	  for(int i=0;i<3;i++)
    52 	    {
    53 	      points.push_back(my_points[i]);
    54 	    }
    55 	  property_points().set_value(points);
    56 	}
    57     }
    58 
    59   if(set_arrow)
    60     {
    61       //calculating coordinates of the direction indicator arrow
    62 
    63       xy<gdouble> target( my_points[2].get_x(), my_points[2].get_y() );
    64       xy<gdouble> center( my_points[1].get_x(), my_points[1].get_y() );
    65 
    66       xy<gdouble> unit_vector_in_dir(target-center);
    67       //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
    68       unit_vector_in_dir/=sqrt( unit_vector_in_dir.normSquare() );
    69       //       std::cout << " = " << unit_vector_in_dir << std::endl;
    70 
    71       xy<gdouble> unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
    72       //       std::cout << unit_norm_vector << std::endl;
    73 
    74       {      
    75 	//       /\             top
    76 	//      /  \
    77 	//      -  -      c(enter)l(eft), ccl, ccr, cr
    78 	//       ||
    79 	//       ||       b(ottom)l, br
    80       }
    81 
    82       double size=3;
    83 
    84       xy<gdouble> bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
    85       xy<gdouble> br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
    86       xy<gdouble> ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
    87       xy<gdouble> ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
    88       xy<gdouble> cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
    89       xy<gdouble> cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
    90       xy<gdouble> top(center + unit_vector_in_dir * 3 * size);
    91 	 
    92       //       std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
    93 
    94       Gnome::Canvas::Points arrow_points;
    95       arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
    96       arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
    97       arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
    98       arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
    99       arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
   100       arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
   101       arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
   102 
   103       arrow->property_points().set_value(arrow_points);
   104     }
   105 }
   106 
   107 bool BrokenEdge::edge_former_event_handler(GdkEvent* e)
   108 {
   109   switch(e->type)
   110     {
   111     case GDK_BUTTON_PRESS:
   112       //we mark the location of the event to be able to calculate parameters of dragging
   113       clicked_x=e->button.x;
   114       clicked_y=e->button.y;
   115       isbutton=true;
   116       break;
   117     case GDK_BUTTON_RELEASE:
   118       isbutton=false;
   119       break;
   120     case GDK_MOTION_NOTIFY:
   121       //we only have to do sg. if the mouse button is pressed
   122       if(isbutton)
   123 	{
   124 	  //new coordinates will be the old values,
   125 	  //because the item will be moved to the
   126 	  //new coordinate therefore the new movement
   127 	  //has to be calculated from here
   128 
   129 	  double dx=e->motion.x-clicked_x;
   130 	  double dy=e->motion.y-clicked_y;
   131 
   132 	  Gnome::Canvas::Points points_new;
   133 
   134 	  points_new.push_back(my_points[0]);
   135 	  points_new.push_back(my_points[1]=Gnome::Art::Point(my_points[1].get_x()+dx,my_points[1].get_y()+dy));
   136 	  points_new.push_back(my_points[2]);
   137 
   138 	  set_points(points_new);
   139 
   140 	  clicked_x=e->motion.x;
   141 	  clicked_y=e->motion.y;
   142 
   143 	}
   144     default: break;
   145     }
   146 
   147   return true;
   148 }