When moving nodes with midbutton little red arrows keep their position.
1 #include "graph_displayer_canvas.h"
4 GraphDisplayerCanvas::EdgeBase::EdgeBase(Gnome::Canvas::Group& _group, Edge _edge, GraphDisplayerCanvas& _canvas) :
5 Gnome::Canvas::Group(_group), edge(_edge), canvas(_canvas), arrow(*this)
7 arrow.property_fill_color().set_value("red");
8 arrow.lower_to_bottom();
11 GraphDisplayerCanvas::EdgeBase::~EdgeBase()
15 void GraphDisplayerCanvas::EdgeBase::drawArrow(XY unit_vector_in_dir)
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);
23 // - - // c(enter)l(eft), ccl, ccr, cr
25 // || // b(ottom)l, br
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);
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 ) );
46 arrow.property_points().set_value(arrow_points);
49 GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g,
50 Edge _edge, GraphDisplayerCanvas & gc) : EdgeBase(g, _edge, gc),
51 isbutton(false), line(*this)
53 arrow.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
55 line.property_fill_color().set_value("green");
56 line.property_width_units().set_value(10);
57 line.lower_to_bottom();
62 GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
66 void GraphDisplayerCanvas::BrokenEdge::draw()
68 MapStorage& ms = canvas.mytab.mapstorage;
70 //calculating coordinates of the direction indicator arrow
71 XY head(ms.coords[ms.graph.target(edge)]);
72 XY center(ms.arrow_pos[edge]);
74 XY unit_vector_in_dir(head-center);
75 double length=sqrt( unit_vector_in_dir.normSquare() );
77 unit_vector_in_dir/=length;
80 drawArrow(unit_vector_in_dir);
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);
95 bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
99 case GDK_BUTTON_PRESS:
100 //we mark the location of the event to be able to calculate parameters
102 if(canvas.getActualTool()!=CREATE_NODE)
104 canvas.toggleEdgeActivity(this, true);
105 clicked_x=e->button.x;
106 clicked_y=e->button.y;
110 case GDK_BUTTON_RELEASE:
111 if(canvas.getActualTool()!=CREATE_NODE)
113 canvas.toggleEdgeActivity(this, false);
117 case GDK_MOTION_NOTIFY:
118 //we only have to do sg. if the mouse button is pressed
121 //new coordinates will be the old values,
122 //because the item will be moved to the
123 //new coordinate therefore the new movement
124 //has to be calculated from here
126 double dx=e->motion.x-clicked_x;
127 double dy=e->motion.y-clicked_y;
129 Gnome::Canvas::Points points_new;
131 canvas.mytab.mapstorage.arrow_pos.set(edge, canvas.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
134 canvas.textReposition(canvas.mytab.mapstorage.arrow_pos[edge]);
136 clicked_x=e->motion.x;
137 clicked_y=e->motion.y;
146 void GraphDisplayerCanvas::BrokenEdge::setLineWidth(int w)
148 line.property_width_units().set_value(w);
151 void GraphDisplayerCanvas::BrokenEdge::setFillColor(Gdk::Color c)
153 line.property_fill_color_gdk().set_value(c);
156 GraphDisplayerCanvas::LoopEdge::LoopEdge(Gnome::Canvas::Group& _group,
157 Edge _edge, GraphDisplayerCanvas& _canvas) :
158 EdgeBase(_group, _edge, _canvas), line(*this)
160 line.property_fill_color().set_value("green");
161 line.property_width_units().set_value(10);
162 line.lower_to_bottom();
167 GraphDisplayerCanvas::LoopEdge::~LoopEdge()
171 void GraphDisplayerCanvas::LoopEdge::draw()
173 MapStorage& ms = canvas.mytab.mapstorage;
175 Node node = ms.graph.source(edge);
176 XY center = (ms.coords[node] + ms.arrow_pos[edge]) / 2.0;
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;
182 drawArrow(unit_vector_in_dir);
185 sqrt((ms.arrow_pos[edge] - ms.coords[node]).normSquare()) / 2.0;
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);
195 void GraphDisplayerCanvas::LoopEdge::setLineWidth(int w)
197 line.property_width_units().set_value(w);
200 void GraphDisplayerCanvas::LoopEdge::setFillColor(Gdk::Color c)
202 line.property_fill_color_gdk().set_value(c);