gdc-broken_edge.cc
changeset 147 10ef59f6633c
parent 98 f60f89147531
child 151 72f1c33f89d4
     1.1 --- a/gdc-broken_edge.cc	Wed Aug 30 15:55:18 2006 +0000
     1.2 +++ b/gdc-broken_edge.cc	Wed Sep 13 09:16:29 2006 +0000
     1.3 @@ -1,133 +1,203 @@
     1.4  #include "graph_displayer_canvas.h"
     1.5  #include <cmath>
     1.6  
     1.7 -GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc) : Line(g), edge(_edge), gdc(gc), isbutton(false)
     1.8 +GraphDisplayerCanvas::EdgeBase::EdgeBase(Gnome::Canvas::Group& _group, Edge _edge, GraphDisplayerCanvas& _canvas) : 
     1.9 +  Gnome::Canvas::Group(_group), edge(_edge), canvas(_canvas), arrow(*this)
    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 +  arrow.property_fill_color().set_value("red");
    1.16 +  arrow.lower_to_bottom();
    1.17 +}
    1.18 +
    1.19 +GraphDisplayerCanvas::EdgeBase::~EdgeBase()
    1.20 +{
    1.21 +}
    1.22 +
    1.23 +void GraphDisplayerCanvas::EdgeBase::drawArrow(XY unit_vector_in_dir)
    1.24 +{
    1.25 +  MapStorage& ms = canvas.mytab.mapstorage;
    1.26 +  XY center(ms.arrow_pos[edge]);
    1.27 +  XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
    1.28 +
    1.29 +  //       /\       // top
    1.30 +  //      /  \      //
    1.31 +  //      -  -      // c(enter)l(eft), ccl, ccr, cr
    1.32 +  //       ||       //
    1.33 +  //       ||       // b(ottom)l, br
    1.34 +
    1.35 +  double size=3;
    1.36 +
    1.37 +  XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
    1.38 +  XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
    1.39 +  XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
    1.40 +  XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
    1.41 +  XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
    1.42 +  XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
    1.43 +  XY top(center + unit_vector_in_dir * 3 * size);
    1.44 +
    1.45 +  Gnome::Canvas::Points arrow_points;
    1.46 +  arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
    1.47 +  arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
    1.48 +  arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
    1.49 +  arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
    1.50 +  arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
    1.51 +  arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
    1.52 +  arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
    1.53 +
    1.54 +  arrow.property_points().set_value(arrow_points);
    1.55 +}
    1.56 +
    1.57 +GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g,
    1.58 +    Edge _edge, GraphDisplayerCanvas & gc) : EdgeBase(g, _edge, gc),
    1.59 +  isbutton(false), line(*this)
    1.60 +{
    1.61 +  arrow.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
    1.62 +
    1.63 +  line.property_fill_color().set_value("green");
    1.64 +  line.property_width_units().set_value(10);    
    1.65 +  line.lower_to_bottom();
    1.66 +
    1.67    draw();
    1.68  }
    1.69  
    1.70  GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
    1.71  {
    1.72 -  if(arrow)delete(arrow);
    1.73  }
    1.74  
    1.75  void GraphDisplayerCanvas::BrokenEdge::draw()
    1.76  {
    1.77 -  MapStorage& ms = gdc.mytab.mapstorage;
    1.78 +  MapStorage& ms = canvas.mytab.mapstorage;
    1.79 +
    1.80 +  //calculating coordinates of the direction indicator arrow
    1.81 +  XY head(ms.coords[ms.graph.target(edge)]);
    1.82 +  XY center(ms.arrow_pos[edge]);
    1.83 +
    1.84 +  XY unit_vector_in_dir(head-center);
    1.85 +  double length=sqrt( unit_vector_in_dir.normSquare() );
    1.86 +
    1.87 +  unit_vector_in_dir/=length;
    1.88 +
    1.89 +  // update the arrow
    1.90 +  drawArrow(unit_vector_in_dir);
    1.91  
    1.92    // update the edge
    1.93 -  {
    1.94 -    Gnome::Canvas::Points points;
    1.95 -    Node source = ms.graph.source(edge);
    1.96 -    Node target = ms.graph.target(edge);
    1.97 -    points.push_back(Gnome::Art::Point(ms.coords[source].x,
    1.98 -          ms.coords[source].y));
    1.99 -    points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
   1.100 -          ms.arrow_pos[edge].y));
   1.101 -    points.push_back(Gnome::Art::Point(ms.coords[target].x,
   1.102 -          ms.coords[target].y));
   1.103 -    property_points().set_value(points);
   1.104 -  }
   1.105 -
   1.106 -  // update the arrow
   1.107 -  {
   1.108 -    //calculating coordinates of the direction indicator arrow
   1.109 -    XY target(ms.coords[ms.graph.target(edge)]);
   1.110 -    XY center(ms.arrow_pos[edge]);
   1.111 -
   1.112 -    XY unit_vector_in_dir(target-center);
   1.113 -    double length=sqrt( unit_vector_in_dir.normSquare() );
   1.114 -
   1.115 -    //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
   1.116 -    unit_vector_in_dir/=length;
   1.117 -    //       std::cout << " = " << unit_vector_in_dir << std::endl;
   1.118 -
   1.119 -    XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
   1.120 -    //       std::cout << unit_norm_vector << std::endl;
   1.121 -
   1.122 -    {      
   1.123 -      //       /\       // top
   1.124 -      //      /  \      //
   1.125 -      //      -  -      // c(enter)l(eft), ccl, ccr, cr
   1.126 -      //       ||       //
   1.127 -      //       ||       // b(ottom)l, br
   1.128 -    }
   1.129 -
   1.130 -    double size=3;
   1.131 -
   1.132 -    XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
   1.133 -    XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
   1.134 -    XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
   1.135 -    XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
   1.136 -    XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
   1.137 -    XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
   1.138 -    XY top(center + unit_vector_in_dir * 3 * size);
   1.139 -
   1.140 -    //std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
   1.141 -
   1.142 -    Gnome::Canvas::Points arrow_points;
   1.143 -    arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
   1.144 -    arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
   1.145 -    arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
   1.146 -    arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
   1.147 -    arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
   1.148 -    arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
   1.149 -    arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
   1.150 -
   1.151 -    arrow->property_points().set_value(arrow_points);
   1.152 -  }
   1.153 +  Gnome::Canvas::Points points;
   1.154 +  Node source = ms.graph.source(edge);
   1.155 +  Node target = ms.graph.target(edge);
   1.156 +  points.push_back(Gnome::Art::Point(ms.coords[source].x,
   1.157 +        ms.coords[source].y));
   1.158 +  points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
   1.159 +        ms.arrow_pos[edge].y));
   1.160 +  points.push_back(Gnome::Art::Point(ms.coords[target].x,
   1.161 +        ms.coords[target].y));
   1.162 +  line.property_points().set_value(points);
   1.163  }
   1.164  
   1.165  bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
   1.166  {
   1.167    switch(e->type)
   1.168 -    {
   1.169 +  {
   1.170      case GDK_BUTTON_PRESS:
   1.171 -      //we mark the location of the event to be able to calculate parameters of dragging
   1.172 -      if(gdc.getActualTool()!=CREATE_NODE)
   1.173 -	{
   1.174 -	  gdc.toggleEdgeActivity(this, true);
   1.175 -	  clicked_x=e->button.x;
   1.176 -	  clicked_y=e->button.y;
   1.177 -	  isbutton=true;
   1.178 -	}
   1.179 +      //we mark the location of the event to be able to calculate parameters
   1.180 +      //of dragging
   1.181 +      if(canvas.getActualTool()!=CREATE_NODE)
   1.182 +      {
   1.183 +        canvas.toggleEdgeActivity(this, true);
   1.184 +        clicked_x=e->button.x;
   1.185 +        clicked_y=e->button.y;
   1.186 +        isbutton=true;
   1.187 +      }
   1.188        break;
   1.189      case GDK_BUTTON_RELEASE:
   1.190 -      if(gdc.getActualTool()!=CREATE_NODE)
   1.191 -	{
   1.192 -	  gdc.toggleEdgeActivity(this, false);
   1.193 -	  isbutton=false;
   1.194 -	}
   1.195 +      if(canvas.getActualTool()!=CREATE_NODE)
   1.196 +      {
   1.197 +        canvas.toggleEdgeActivity(this, false);
   1.198 +        isbutton=false;
   1.199 +      }
   1.200        break;
   1.201      case GDK_MOTION_NOTIFY:
   1.202        //we only have to do sg. if the mouse button is pressed
   1.203        if(isbutton)
   1.204 -	{
   1.205 -	  //new coordinates will be the old values,
   1.206 -	  //because the item will be moved to the
   1.207 -	  //new coordinate therefore the new movement
   1.208 -	  //has to be calculated from here
   1.209 +      {
   1.210 +        //new coordinates will be the old values,
   1.211 +        //because the item will be moved to the
   1.212 +        //new coordinate therefore the new movement
   1.213 +        //has to be calculated from here
   1.214  
   1.215 -	  double dx=e->motion.x-clicked_x;
   1.216 -	  double dy=e->motion.y-clicked_y;
   1.217 +        double dx=e->motion.x-clicked_x;
   1.218 +        double dy=e->motion.y-clicked_y;
   1.219  
   1.220 -	  Gnome::Canvas::Points points_new;
   1.221 +        Gnome::Canvas::Points points_new;
   1.222  
   1.223 -          gdc.mytab.mapstorage.arrow_pos.set(edge, gdc.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
   1.224 +        canvas.mytab.mapstorage.arrow_pos.set(edge, canvas.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
   1.225  
   1.226 -	  draw();
   1.227 -	  gdc.textReposition(gdc.mytab.mapstorage.arrow_pos[edge]);
   1.228 +        draw();
   1.229 +        canvas.textReposition(canvas.mytab.mapstorage.arrow_pos[edge]);
   1.230  
   1.231 -	  clicked_x=e->motion.x;
   1.232 -	  clicked_y=e->motion.y;
   1.233 +        clicked_x=e->motion.x;
   1.234 +        clicked_y=e->motion.y;
   1.235  
   1.236 -	}
   1.237 +      }
   1.238      default: break;
   1.239 -    }
   1.240 +  }
   1.241  
   1.242    return true;
   1.243  }
   1.244 +
   1.245 +void GraphDisplayerCanvas::BrokenEdge::setLineWidth(int w)
   1.246 +{
   1.247 +  line.property_width_units().set_value(w);
   1.248 +}
   1.249 +
   1.250 +void GraphDisplayerCanvas::BrokenEdge::setFillColor(Gdk::Color c)
   1.251 +{
   1.252 +  line.property_fill_color_gdk().set_value(c);
   1.253 +}
   1.254 +
   1.255 +GraphDisplayerCanvas::LoopEdge::LoopEdge(Gnome::Canvas::Group& _group,
   1.256 +    Edge _edge, GraphDisplayerCanvas& _canvas) :
   1.257 +  EdgeBase(_group, _edge, _canvas), line(*this)
   1.258 +{
   1.259 +  line.property_fill_color().set_value("green");
   1.260 +  line.property_width_units().set_value(10);    
   1.261 +  line.lower_to_bottom();
   1.262 +
   1.263 +  draw();
   1.264 +}
   1.265 +
   1.266 +GraphDisplayerCanvas::LoopEdge::~LoopEdge()
   1.267 +{
   1.268 +}
   1.269 +
   1.270 +void GraphDisplayerCanvas::LoopEdge::draw()
   1.271 +{
   1.272 +  MapStorage& ms = canvas.mytab.mapstorage;
   1.273 +
   1.274 +  Node node = ms.graph.source(edge);
   1.275 +  XY center = (ms.coords[node] + ms.arrow_pos[edge]) / 2.0;
   1.276 +
   1.277 +  XY unit_vector_in_dir(rot90(center - ms.arrow_pos[edge]));
   1.278 +  double length = sqrt(unit_vector_in_dir.normSquare());
   1.279 +  unit_vector_in_dir /= length;
   1.280 +
   1.281 +  drawArrow(unit_vector_in_dir);
   1.282 +
   1.283 +  double radius =
   1.284 +    sqrt((ms.arrow_pos[edge] - ms.coords[node]).normSquare()) / 2.0;
   1.285 +
   1.286 +  XY p1 = center + XY(-radius,  radius);
   1.287 +  XY p2 = center + XY( radius, -radius);
   1.288 +  line.property_x1().set_value(p1.x);
   1.289 +  line.property_y1().set_value(p1.y);
   1.290 +  line.property_x2().set_value(p2.x);
   1.291 +  line.property_y2().set_value(p2.y);
   1.292 +}
   1.293 +
   1.294 +void GraphDisplayerCanvas::LoopEdge::setLineWidth(int w)
   1.295 +{
   1.296 +  line.property_width_units().set_value(w);
   1.297 +}
   1.298 +
   1.299 +void GraphDisplayerCanvas::LoopEdge::setFillColor(Gdk::Color c)
   1.300 +{
   1.301 +  line.property_fill_color_gdk().set_value(c);
   1.302 +}