gui/gdc-broken_edge.cc
changeset 1819 fd82adfbe905
parent 1714 66c89fe52d4e
child 1831 75ab76fc4bf2
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gui/gdc-broken_edge.cc	Mon Nov 21 12:07:05 2005 +0000
     1.3 @@ -0,0 +1,214 @@
     1.4 +#include "graph_displayer_canvas.h"
     1.5 +#include <cmath>
     1.6 +
     1.7 +GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Gnome::Canvas::Points p, GraphDisplayerCanvas & gc) : Line(g), gdc(gc), isbutton(false)
     1.8 +{
     1.9 +  my_points=new Gnome::Art::Point[3];
    1.10 +
    1.11 +  arrow=new Gnome::Canvas::Polygon(g);
    1.12 +  *arrow << Gnome::Canvas::Properties::fill_color("red");
    1.13 +  arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
    1.14 +  arrow->lower_to_bottom();
    1.15 +  setPoints(p);
    1.16 +}
    1.17 +
    1.18 +GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
    1.19 +{
    1.20 +  if(arrow)delete(arrow);
    1.21 +}
    1.22 +
    1.23 +void GraphDisplayerCanvas::BrokenEdge::setPoints(Gnome::Canvas::Points p, bool move)
    1.24 +{
    1.25 +  bool set_arrow=false;
    1.26 +  //red arrow losts its position-right button
    1.27 +  if(!move)
    1.28 +    {
    1.29 +      if(p.size()==2)
    1.30 +	{
    1.31 +	  set_arrow=true;
    1.32 +	  Gnome::Canvas::Points points_with_center;
    1.33 +	  points_with_center.push_back(my_points[0]=p[0]);
    1.34 +	  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 );
    1.35 +	  points_with_center.push_back(my_points[2]=p[1]);
    1.36 +	  property_points().set_value(points_with_center);
    1.37 +	}  
    1.38 +      if(p.size()==3)
    1.39 +	{
    1.40 +	  set_arrow=true;
    1.41 +	  property_points().set_value(p);
    1.42 +	  for(int i=0;i<3;i++)
    1.43 +	    {
    1.44 +	      my_points[i]=p[i];
    1.45 +	    }
    1.46 +	}
    1.47 +    }
    1.48 +  else
    1.49 +    {
    1.50 +      //arrow keeps its position-left button
    1.51 +
    1.52 +//       if(p.size()==2)
    1.53 +//       	{
    1.54 +//       	  Gnome::Canvas::Points points;
    1.55 +//       	  my_points[0]=p[0];
    1.56 +//       	  my_points[2]=p[1];
    1.57 +//       	  for(int i=0;i<3;i++)
    1.58 +//       	    {
    1.59 +//       	      points.push_back(my_points[i]);
    1.60 +//       	    }
    1.61 +//       	  property_points().set_value(points);
    1.62 +//       	}
    1.63 +      set_arrow=true;
    1.64 +
    1.65 +      //////////////////////////////////////////////////////////////////////////////////////////////////////
    1.66 +      /////////// keeps shape-with scalar multiplication - version 2.
    1.67 +      //////////////////////////////////////////////////////////////////////////////////////////////////////
    1.68 +
    1.69 +      if(p.size()==2)
    1.70 +      	{
    1.71 +	  //old vector from one to the other node - a
    1.72 +	  xy<double> a_v(my_points[2].get_x()-my_points[0].get_x(),my_points[2].get_y()-my_points[0].get_y());
    1.73 +	  //new vector from one to the other node - b
    1.74 +	  xy<double> b_v(p[1].get_x()-p[0].get_x(),p[1].get_y()-p[0].get_y());
    1.75 +
    1.76 +	  double absa=sqrt(a_v.normSquare());
    1.77 +	  double absb=sqrt(b_v.normSquare());
    1.78 +
    1.79 +	  //old vector from one node to the breakpoint - c
    1.80 +	  xy<double> c_v(my_points[1].get_x()-my_points[0].get_x(),my_points[1].get_y()-my_points[0].get_y());
    1.81 +
    1.82 +	  //unit vector with the same direction to a_v
    1.83 +	  xy<double> a_v_u(a_v.x/absa,a_v.y/absa);
    1.84 +
    1.85 +	  //normal vector of unit vector with the same direction to a_v
    1.86 +	  xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
    1.87 +
    1.88 +	  //unit vector with the same direction to b_v
    1.89 +	  xy<double> b_v_u(b_v.x/absb,b_v.y/absb);
    1.90 +
    1.91 +	  //normal vector of unit vector with the same direction to b_v
    1.92 +	  xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
    1.93 +
    1.94 +	  //vector c in a_v_u and a_v_u_n co-ordinate system
    1.95 +	  xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n);
    1.96 +
    1.97 +	  //new vector from one node to the breakpoint - d - we have to calculate this one
    1.98 +	  xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
    1.99 +
   1.100 +	  my_points[1]=Gnome::Art::Point(d_v.x+p[0].get_x(),d_v.y+p[0].get_y());
   1.101 +
   1.102 +      	  my_points[0]=p[0];
   1.103 +      	  my_points[2]=p[1];
   1.104 +
   1.105 +	  Gnome::Canvas::Points points;
   1.106 +	  for(int i=0;i<3;i++)
   1.107 +	    {
   1.108 +	      points.push_back(my_points[i]);
   1.109 +	    }
   1.110 +	  property_points().set_value(points);
   1.111 +	}
   1.112 +    }
   1.113 +  if(set_arrow)
   1.114 +    {
   1.115 +      //calculating coordinates of the direction indicator arrow
   1.116 +
   1.117 +      xy<gdouble> target( my_points[2].get_x(), my_points[2].get_y() );
   1.118 +      xy<gdouble> center( my_points[1].get_x(), my_points[1].get_y() );
   1.119 +
   1.120 +      xy<gdouble> unit_vector_in_dir(target-center);
   1.121 +      //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
   1.122 +      unit_vector_in_dir/=sqrt( unit_vector_in_dir.normSquare() );
   1.123 +      //       std::cout << " = " << unit_vector_in_dir << std::endl;
   1.124 +
   1.125 +      xy<gdouble> unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
   1.126 +      //       std::cout << unit_norm_vector << std::endl;
   1.127 +
   1.128 +      {      
   1.129 +	//       /\       // top
   1.130 +	//      /  \      //
   1.131 +	//      -  -      // c(enter)l(eft), ccl, ccr, cr
   1.132 +	//       ||       //
   1.133 +	//       ||       // b(ottom)l, br
   1.134 +      }
   1.135 +
   1.136 +      double size=3;
   1.137 +
   1.138 +      xy<gdouble> bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
   1.139 +      xy<gdouble> br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
   1.140 +      xy<gdouble> ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
   1.141 +      xy<gdouble> ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
   1.142 +      xy<gdouble> cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
   1.143 +      xy<gdouble> cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
   1.144 +      xy<gdouble> top(center + unit_vector_in_dir * 3 * size);
   1.145 +	 
   1.146 +      //       std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
   1.147 +
   1.148 +      Gnome::Canvas::Points arrow_points;
   1.149 +      arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
   1.150 +      arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
   1.151 +      arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
   1.152 +      arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
   1.153 +      arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
   1.154 +      arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
   1.155 +      arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
   1.156 +
   1.157 +      arrow->property_points().set_value(arrow_points);
   1.158 +    }
   1.159 +}
   1.160 +
   1.161 +bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
   1.162 +{
   1.163 +  switch(e->type)
   1.164 +    {
   1.165 +    case GDK_BUTTON_PRESS:
   1.166 +      //we mark the location of the event to be able to calculate parameters of dragging
   1.167 +      if(gdc.getActualTool()!=CREATE_NODE)
   1.168 +	{
   1.169 +	  gdc.toggleEdgeActivity(this, true);
   1.170 +	  clicked_x=e->button.x;
   1.171 +	  clicked_y=e->button.y;
   1.172 +	  isbutton=true;
   1.173 +	}
   1.174 +      break;
   1.175 +    case GDK_BUTTON_RELEASE:
   1.176 +      if(gdc.getActualTool()!=CREATE_NODE)
   1.177 +	{
   1.178 +	  gdc.toggleEdgeActivity(this, false);
   1.179 +	  isbutton=false;
   1.180 +	}
   1.181 +      break;
   1.182 +    case GDK_MOTION_NOTIFY:
   1.183 +      //we only have to do sg. if the mouse button is pressed
   1.184 +      if(isbutton)
   1.185 +	{
   1.186 +	  //new coordinates will be the old values,
   1.187 +	  //because the item will be moved to the
   1.188 +	  //new coordinate therefore the new movement
   1.189 +	  //has to be calculated from here
   1.190 +
   1.191 +	  double dx=e->motion.x-clicked_x;
   1.192 +	  double dy=e->motion.y-clicked_y;
   1.193 +
   1.194 +	  Gnome::Canvas::Points points_new;
   1.195 +
   1.196 +	  points_new.push_back(my_points[0]);
   1.197 +	  points_new.push_back(my_points[1]=Gnome::Art::Point(my_points[1].get_x()+dx,my_points[1].get_y()+dy));
   1.198 +	  points_new.push_back(my_points[2]);
   1.199 +
   1.200 +	  setPoints(points_new);
   1.201 +	  gdc.textReposition(xy<double>(my_points[1].get_x(),my_points[1].get_y()));
   1.202 +
   1.203 +	  clicked_x=e->motion.x;
   1.204 +	  clicked_y=e->motion.y;
   1.205 +
   1.206 +	}
   1.207 +    default: break;
   1.208 +    }
   1.209 +
   1.210 +  return true;
   1.211 +}
   1.212 +
   1.213 +xy<double> GraphDisplayerCanvas::BrokenEdge::getArrowPos()
   1.214 +{
   1.215 +  xy<double> ret_val(my_points[1].get_x(),my_points[1].get_y());
   1.216 +  return ret_val;
   1.217 +}