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 +}