COIN-OR::LEMON - Graph Library

source: glemon-0.x/gdc-broken_edge.cc @ 147:10ef59f6633c

Last change on this file since 147:10ef59f6633c was 147:10ef59f6633c, checked in by Akos Ladanyi, 13 years ago

Loop edges.

File size: 5.9 KB
Line 
1#include "graph_displayer_canvas.h"
2#include <cmath>
3
4GraphDisplayerCanvas::EdgeBase::EdgeBase(Gnome::Canvas::Group& _group, Edge _edge, GraphDisplayerCanvas& _canvas) :
5  Gnome::Canvas::Group(_group), edge(_edge), canvas(_canvas), arrow(*this)
6{
7  arrow.property_fill_color().set_value("red");
8  arrow.lower_to_bottom();
9}
10
11GraphDisplayerCanvas::EdgeBase::~EdgeBase()
12{
13}
14
15void 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
49GraphDisplayerCanvas::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
59  draw();
60}
61
62GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
63{
64}
65
66void GraphDisplayerCanvas::BrokenEdge::draw()
67{
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);
81
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
95bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
96{
97  switch(e->type)
98  {
99    case GDK_BUTTON_PRESS:
100      //we mark the location of the event to be able to calculate parameters
101      //of dragging
102      if(canvas.getActualTool()!=CREATE_NODE)
103      {
104        canvas.toggleEdgeActivity(this, true);
105        clicked_x=e->button.x;
106        clicked_y=e->button.y;
107        isbutton=true;
108      }
109      break;
110    case GDK_BUTTON_RELEASE:
111      if(canvas.getActualTool()!=CREATE_NODE)
112      {
113        canvas.toggleEdgeActivity(this, false);
114        isbutton=false;
115      }
116      break;
117    case GDK_MOTION_NOTIFY:
118      //we only have to do sg. if the mouse button is pressed
119      if(isbutton)
120      {
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
125
126        double dx=e->motion.x-clicked_x;
127        double dy=e->motion.y-clicked_y;
128
129        Gnome::Canvas::Points points_new;
130
131        canvas.mytab.mapstorage.arrow_pos.set(edge, canvas.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
132
133        draw();
134        canvas.textReposition(canvas.mytab.mapstorage.arrow_pos[edge]);
135
136        clicked_x=e->motion.x;
137        clicked_y=e->motion.y;
138
139      }
140    default: break;
141  }
142
143  return true;
144}
145
146void GraphDisplayerCanvas::BrokenEdge::setLineWidth(int w)
147{
148  line.property_width_units().set_value(w);
149}
150
151void GraphDisplayerCanvas::BrokenEdge::setFillColor(Gdk::Color c)
152{
153  line.property_fill_color_gdk().set_value(c);
154}
155
156GraphDisplayerCanvas::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
167GraphDisplayerCanvas::LoopEdge::~LoopEdge()
168{
169}
170
171void 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
195void GraphDisplayerCanvas::LoopEdge::setLineWidth(int w)
196{
197  line.property_width_units().set_value(w);
198}
199
200void GraphDisplayerCanvas::LoopEdge::setFillColor(Gdk::Color c)
201{
202  line.property_fill_color_gdk().set_value(c);
203}
Note: See TracBrowser for help on using the repository browser.