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