gdc-broken_edge.cc
changeset 150 86273bfe0e4d
parent 98 f60f89147531
child 151 72f1c33f89d4
equal deleted inserted replaced
2:158ea9c252bf 3:2465b34adaa4
     1 #include "graph_displayer_canvas.h"
     1 #include "graph_displayer_canvas.h"
     2 #include <cmath>
     2 #include <cmath>
     3 
     3 
     4 GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc) : Line(g), edge(_edge), gdc(gc), isbutton(false)
     4 GraphDisplayerCanvas::EdgeBase::EdgeBase(Gnome::Canvas::Group& _group, Edge _edge, GraphDisplayerCanvas& _canvas) : 
     5 {
     5   Gnome::Canvas::Group(_group), edge(_edge), canvas(_canvas), arrow(*this)
     6   arrow=new Gnome::Canvas::Polygon(g);
     6 {
     7   *arrow << Gnome::Canvas::Properties::fill_color("red");
     7   arrow.property_fill_color().set_value("red");
     8   arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
     8   arrow.lower_to_bottom();
     9   arrow->lower_to_bottom();
     9 }
       
    10 
       
    11 GraphDisplayerCanvas::EdgeBase::~EdgeBase()
       
    12 {
       
    13 }
       
    14 
       
    15 void GraphDisplayerCanvas::EdgeBase::drawArrow(XY unit_vector_in_dir)
       
    16 {
       
    17   MapStorage& ms = canvas.mytab.mapstorage;
       
    18   XY center(ms.arrow_pos[edge]);
       
    19   XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
       
    20 
       
    21   //       /\       // top
       
    22   //      /  \      //
       
    23   //      -  -      // c(enter)l(eft), ccl, ccr, cr
       
    24   //       ||       //
       
    25   //       ||       // b(ottom)l, br
       
    26 
       
    27   double size=3;
       
    28 
       
    29   XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
       
    30   XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
       
    31   XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
       
    32   XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
       
    33   XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
       
    34   XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
       
    35   XY top(center + unit_vector_in_dir * 3 * size);
       
    36 
       
    37   Gnome::Canvas::Points arrow_points;
       
    38   arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
       
    39   arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
       
    40   arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
       
    41   arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
       
    42   arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
       
    43   arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
       
    44   arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
       
    45 
       
    46   arrow.property_points().set_value(arrow_points);
       
    47 }
       
    48 
       
    49 GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g,
       
    50     Edge _edge, GraphDisplayerCanvas & gc) : EdgeBase(g, _edge, gc),
       
    51   isbutton(false), line(*this)
       
    52 {
       
    53   arrow.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
       
    54 
       
    55   line.property_fill_color().set_value("green");
       
    56   line.property_width_units().set_value(10);    
       
    57   line.lower_to_bottom();
       
    58 
    10   draw();
    59   draw();
    11 }
    60 }
    12 
    61 
    13 GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
    62 GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
    14 {
    63 {
    15   if(arrow)delete(arrow);
       
    16 }
    64 }
    17 
    65 
    18 void GraphDisplayerCanvas::BrokenEdge::draw()
    66 void GraphDisplayerCanvas::BrokenEdge::draw()
    19 {
    67 {
    20   MapStorage& ms = gdc.mytab.mapstorage;
    68   MapStorage& ms = canvas.mytab.mapstorage;
       
    69 
       
    70   //calculating coordinates of the direction indicator arrow
       
    71   XY head(ms.coords[ms.graph.target(edge)]);
       
    72   XY center(ms.arrow_pos[edge]);
       
    73 
       
    74   XY unit_vector_in_dir(head-center);
       
    75   double length=sqrt( unit_vector_in_dir.normSquare() );
       
    76 
       
    77   unit_vector_in_dir/=length;
       
    78 
       
    79   // update the arrow
       
    80   drawArrow(unit_vector_in_dir);
    21 
    81 
    22   // update the edge
    82   // update the edge
       
    83   Gnome::Canvas::Points points;
       
    84   Node source = ms.graph.source(edge);
       
    85   Node target = ms.graph.target(edge);
       
    86   points.push_back(Gnome::Art::Point(ms.coords[source].x,
       
    87         ms.coords[source].y));
       
    88   points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
       
    89         ms.arrow_pos[edge].y));
       
    90   points.push_back(Gnome::Art::Point(ms.coords[target].x,
       
    91         ms.coords[target].y));
       
    92   line.property_points().set_value(points);
       
    93 }
       
    94 
       
    95 bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
       
    96 {
       
    97   switch(e->type)
    23   {
    98   {
    24     Gnome::Canvas::Points points;
       
    25     Node source = ms.graph.source(edge);
       
    26     Node target = ms.graph.target(edge);
       
    27     points.push_back(Gnome::Art::Point(ms.coords[source].x,
       
    28           ms.coords[source].y));
       
    29     points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
       
    30           ms.arrow_pos[edge].y));
       
    31     points.push_back(Gnome::Art::Point(ms.coords[target].x,
       
    32           ms.coords[target].y));
       
    33     property_points().set_value(points);
       
    34   }
       
    35 
       
    36   // update the arrow
       
    37   {
       
    38     //calculating coordinates of the direction indicator arrow
       
    39     XY target(ms.coords[ms.graph.target(edge)]);
       
    40     XY center(ms.arrow_pos[edge]);
       
    41 
       
    42     XY unit_vector_in_dir(target-center);
       
    43     double length=sqrt( unit_vector_in_dir.normSquare() );
       
    44 
       
    45     //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
       
    46     unit_vector_in_dir/=length;
       
    47     //       std::cout << " = " << unit_vector_in_dir << std::endl;
       
    48 
       
    49     XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
       
    50     //       std::cout << unit_norm_vector << std::endl;
       
    51 
       
    52     {      
       
    53       //       /\       // top
       
    54       //      /  \      //
       
    55       //      -  -      // c(enter)l(eft), ccl, ccr, cr
       
    56       //       ||       //
       
    57       //       ||       // b(ottom)l, br
       
    58     }
       
    59 
       
    60     double size=3;
       
    61 
       
    62     XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
       
    63     XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
       
    64     XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
       
    65     XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
       
    66     XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
       
    67     XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
       
    68     XY top(center + unit_vector_in_dir * 3 * size);
       
    69 
       
    70     //std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
       
    71 
       
    72     Gnome::Canvas::Points arrow_points;
       
    73     arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
       
    74     arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
       
    75     arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
       
    76     arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
       
    77     arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
       
    78     arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
       
    79     arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
       
    80 
       
    81     arrow->property_points().set_value(arrow_points);
       
    82   }
       
    83 }
       
    84 
       
    85 bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
       
    86 {
       
    87   switch(e->type)
       
    88     {
       
    89     case GDK_BUTTON_PRESS:
    99     case GDK_BUTTON_PRESS:
    90       //we mark the location of the event to be able to calculate parameters of dragging
   100       //we mark the location of the event to be able to calculate parameters
    91       if(gdc.getActualTool()!=CREATE_NODE)
   101       //of dragging
    92 	{
   102       if(canvas.getActualTool()!=CREATE_NODE)
    93 	  gdc.toggleEdgeActivity(this, true);
   103       {
    94 	  clicked_x=e->button.x;
   104         canvas.toggleEdgeActivity(this, true);
    95 	  clicked_y=e->button.y;
   105         clicked_x=e->button.x;
    96 	  isbutton=true;
   106         clicked_y=e->button.y;
    97 	}
   107         isbutton=true;
       
   108       }
    98       break;
   109       break;
    99     case GDK_BUTTON_RELEASE:
   110     case GDK_BUTTON_RELEASE:
   100       if(gdc.getActualTool()!=CREATE_NODE)
   111       if(canvas.getActualTool()!=CREATE_NODE)
   101 	{
   112       {
   102 	  gdc.toggleEdgeActivity(this, false);
   113         canvas.toggleEdgeActivity(this, false);
   103 	  isbutton=false;
   114         isbutton=false;
   104 	}
   115       }
   105       break;
   116       break;
   106     case GDK_MOTION_NOTIFY:
   117     case GDK_MOTION_NOTIFY:
   107       //we only have to do sg. if the mouse button is pressed
   118       //we only have to do sg. if the mouse button is pressed
   108       if(isbutton)
   119       if(isbutton)
   109 	{
   120       {
   110 	  //new coordinates will be the old values,
   121         //new coordinates will be the old values,
   111 	  //because the item will be moved to the
   122         //because the item will be moved to the
   112 	  //new coordinate therefore the new movement
   123         //new coordinate therefore the new movement
   113 	  //has to be calculated from here
   124         //has to be calculated from here
   114 
   125 
   115 	  double dx=e->motion.x-clicked_x;
   126         double dx=e->motion.x-clicked_x;
   116 	  double dy=e->motion.y-clicked_y;
   127         double dy=e->motion.y-clicked_y;
   117 
   128 
   118 	  Gnome::Canvas::Points points_new;
   129         Gnome::Canvas::Points points_new;
   119 
   130 
   120           gdc.mytab.mapstorage.arrow_pos.set(edge, gdc.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
   131         canvas.mytab.mapstorage.arrow_pos.set(edge, canvas.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
   121 
   132 
   122 	  draw();
   133         draw();
   123 	  gdc.textReposition(gdc.mytab.mapstorage.arrow_pos[edge]);
   134         canvas.textReposition(canvas.mytab.mapstorage.arrow_pos[edge]);
   124 
   135 
   125 	  clicked_x=e->motion.x;
   136         clicked_x=e->motion.x;
   126 	  clicked_y=e->motion.y;
   137         clicked_y=e->motion.y;
   127 
   138 
   128 	}
   139       }
   129     default: break;
   140     default: break;
   130     }
   141   }
   131 
   142 
   132   return true;
   143   return true;
   133 }
   144 }
       
   145 
       
   146 void GraphDisplayerCanvas::BrokenEdge::setLineWidth(int w)
       
   147 {
       
   148   line.property_width_units().set_value(w);
       
   149 }
       
   150 
       
   151 void GraphDisplayerCanvas::BrokenEdge::setFillColor(Gdk::Color c)
       
   152 {
       
   153   line.property_fill_color_gdk().set_value(c);
       
   154 }
       
   155 
       
   156 GraphDisplayerCanvas::LoopEdge::LoopEdge(Gnome::Canvas::Group& _group,
       
   157     Edge _edge, GraphDisplayerCanvas& _canvas) :
       
   158   EdgeBase(_group, _edge, _canvas), line(*this)
       
   159 {
       
   160   line.property_fill_color().set_value("green");
       
   161   line.property_width_units().set_value(10);    
       
   162   line.lower_to_bottom();
       
   163 
       
   164   draw();
       
   165 }
       
   166 
       
   167 GraphDisplayerCanvas::LoopEdge::~LoopEdge()
       
   168 {
       
   169 }
       
   170 
       
   171 void GraphDisplayerCanvas::LoopEdge::draw()
       
   172 {
       
   173   MapStorage& ms = canvas.mytab.mapstorage;
       
   174 
       
   175   Node node = ms.graph.source(edge);
       
   176   XY center = (ms.coords[node] + ms.arrow_pos[edge]) / 2.0;
       
   177 
       
   178   XY unit_vector_in_dir(rot90(center - ms.arrow_pos[edge]));
       
   179   double length = sqrt(unit_vector_in_dir.normSquare());
       
   180   unit_vector_in_dir /= length;
       
   181 
       
   182   drawArrow(unit_vector_in_dir);
       
   183 
       
   184   double radius =
       
   185     sqrt((ms.arrow_pos[edge] - ms.coords[node]).normSquare()) / 2.0;
       
   186 
       
   187   XY p1 = center + XY(-radius,  radius);
       
   188   XY p2 = center + XY( radius, -radius);
       
   189   line.property_x1().set_value(p1.x);
       
   190   line.property_y1().set_value(p1.y);
       
   191   line.property_x2().set_value(p2.x);
       
   192   line.property_y2().set_value(p2.y);
       
   193 }
       
   194 
       
   195 void GraphDisplayerCanvas::LoopEdge::setLineWidth(int w)
       
   196 {
       
   197   line.property_width_units().set_value(w);
       
   198 }
       
   199 
       
   200 void GraphDisplayerCanvas::LoopEdge::setFillColor(Gdk::Color c)
       
   201 {
       
   202   line.property_fill_color_gdk().set_value(c);
       
   203 }