COIN-OR::LEMON - Graph Library

source: glemon/gdc-broken_edge.cc @ 3:2cc5ed6e6255

Last change on this file since 3:2cc5ed6e6255 was 1:67188bd752db, checked in by Peter Hegyi <hegyi@…>, 16 years ago

SVN revision 3500 made compilable with Lemon 1.0.

File size: 7.5 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
12 *
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
15 * purpose.
16 *
17 */
18
19#include <graph_displayer_canvas.h>
20#include <mapstorage.h>
21#include <nbtab.h>
22#include <cmath>
23
24DigraphDisplayerCanvas::ArcBase::ArcBase(Gnome::Canvas::Group& _group, Arc _arc, DigraphDisplayerCanvas& _canvas) :
25  Gnome::Canvas::Group(_group), arc(_arc), canvas(_canvas), arrow(*this)
26{
27  arrow.property_fill_color().set_value("red");
28  arrow.lower_to_bottom();
29  lower_to_bottom();
30}
31
32DigraphDisplayerCanvas::ArcBase::~ArcBase()
33{
34}
35
36void DigraphDisplayerCanvas::ArcBase::drawArrow(XY unit_vector_in_dir)
37{
38  MapStorage& ms = *canvas.mytab.mapstorage;
39  XY center(ms.getArrowCoords(arc));
40  XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
41
42  //       /\       // top
43  //      /  \      //
44  //      -  -      // c(enter)l(eft), ccl, ccr, cr
45  //       ||       //
46  //       ||       // b(ottom)l, br
47
48  double size=3;
49
50  XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
51  XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
52  XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
53  XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
54  XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
55  XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
56  XY top(center + unit_vector_in_dir * 3 * size);
57
58  Gnome::Canvas::Points arrow_points;
59  arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
60  arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
61  arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
62  arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
63  arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
64  arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
65  arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
66
67  arrow.property_points().set_value(arrow_points);
68}
69
70DigraphDisplayerCanvas::BrokenArc::BrokenArc(Gnome::Canvas::Group & g,
71    Arc _arc, DigraphDisplayerCanvas & gc) : ArcBase(g, _arc, gc),
72  isbutton(false), line(*this)
73{
74  arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler));
75
76  line.property_fill_color().set_value("green");
77  line.property_width_units().set_value(10);   
78  line.lower_to_bottom();
79
80  draw();
81}
82
83DigraphDisplayerCanvas::BrokenArc::~BrokenArc()
84{
85}
86
87void DigraphDisplayerCanvas::BrokenArc::draw()
88{
89  MapStorage& ms = *canvas.mytab.mapstorage;
90
91  //calculating coordinates of the direction indicator arrow
92  XY head(ms.getNodeCoords(ms.digraph.target(arc)));
93  XY center(ms.getArrowCoords(arc));
94
95  XY unit_vector_in_dir(head-center);
96  double length=sqrt( unit_vector_in_dir.normSquare() );
97
98  if(length!=0)
99    {
100      unit_vector_in_dir/=length;
101    }
102
103  // update the arrow
104  drawArrow(unit_vector_in_dir);
105
106  // update the arc
107  Gnome::Canvas::Points points;
108  Node source = ms.digraph.source(arc);
109  Node target = ms.digraph.target(arc);
110  points.push_back(Gnome::Art::Point(ms.getNodeCoords(source).x,
111        ms.getNodeCoords(source).y));
112  points.push_back(Gnome::Art::Point(ms.getArrowCoords(arc).x,
113        ms.getArrowCoords(arc).y));
114  points.push_back(Gnome::Art::Point(ms.getNodeCoords(target).x,
115        ms.getNodeCoords(target).y));
116  line.property_points().set_value(points);
117}
118
119bool DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler(GdkEvent* e)
120{
121  switch(e->type)
122  {
123    case GDK_BUTTON_PRESS:
124      //we mark the location of the event to be able to calculate parameters
125      //of dragging
126      if(canvas.getActualTool()!=CREATE_NODE)
127      {
128        canvas.toggleArcActivity(this, true);
129        clicked_x=e->button.x;
130        clicked_y=e->button.y;
131        isbutton=true;
132      }
133      break;
134    case GDK_BUTTON_RELEASE:
135      if(canvas.getActualTool()!=CREATE_NODE)
136      {
137        canvas.toggleArcActivity(this, false);
138        isbutton=false;
139      }
140      break;
141    case GDK_MOTION_NOTIFY:
142      //we only have to do sg. if the mouse button is pressed
143      if(isbutton)
144      {
145        //new coordinates will be the old values,
146        //because the item will be moved to the
147        //new coordinate therefore the new movement
148        //has to be calculated from here
149
150        double dx=e->motion.x-clicked_x;
151        double dy=e->motion.y-clicked_y;
152
153        Gnome::Canvas::Points points_new;
154
155        canvas.mytab.mapstorage->setArrowCoords(arc, canvas.mytab.mapstorage->getArrowCoords(arc) + XY(dx, dy));
156
157        draw();
158        canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));
159
160        clicked_x=e->motion.x;
161        clicked_y=e->motion.y;
162
163      }
164    default: break;
165  }
166
167  return true;
168}
169
170void DigraphDisplayerCanvas::BrokenArc::setLineWidth(int w)
171{
172  line.property_width_units().set_value(w);
173}
174
175void DigraphDisplayerCanvas::BrokenArc::setFillColor(Gdk::Color c)
176{
177  line.property_fill_color_gdk().set_value(c);
178}
179
180DigraphDisplayerCanvas::LoopArc::LoopArc(Gnome::Canvas::Group& _group,
181    Arc _arc, DigraphDisplayerCanvas& _canvas) :
182  ArcBase(_group, _arc, _canvas), line(*this), isbutton(false)
183{
184  arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler));
185
186  line.property_outline_color().set_value("green");
187  line.property_width_units().set_value(10);
188  line.lower_to_bottom();
189
190  draw();
191}
192
193DigraphDisplayerCanvas::LoopArc::~LoopArc()
194{
195}
196
197void DigraphDisplayerCanvas::LoopArc::draw()
198{
199  MapStorage& ms = *canvas.mytab.mapstorage;
200
201  Node node = ms.digraph.source(arc);
202  XY center = (ms.getNodeCoords(node) + ms.getArrowCoords(arc)) / 2.0;
203
204  XY unit_vector_in_dir(rot90(center - ms.getArrowCoords(arc)));
205  double length = sqrt(unit_vector_in_dir.normSquare());
206  unit_vector_in_dir /= length;
207
208  drawArrow(unit_vector_in_dir);
209
210  double radius =
211    sqrt((ms.getArrowCoords(arc) - ms.getNodeCoords(node)).normSquare()) / 2.0;
212
213  XY p1 = center + XY(-radius,  radius);
214  XY p2 = center + XY( radius, -radius);
215  line.property_x1().set_value(p1.x);
216  line.property_y1().set_value(p1.y);
217  line.property_x2().set_value(p2.x);
218  line.property_y2().set_value(p2.y);
219}
220
221void DigraphDisplayerCanvas::LoopArc::setLineWidth(int w)
222{
223  line.property_width_units().set_value(w);
224}
225
226void DigraphDisplayerCanvas::LoopArc::setFillColor(Gdk::Color c)
227{
228  line.property_outline_color_gdk().set_value(c);
229}
230
231bool DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler(GdkEvent* e)
232{
233  switch(e->type)
234  {
235    case GDK_BUTTON_PRESS:
236      if(canvas.getActualTool()!=CREATE_NODE)
237      {
238        canvas.toggleArcActivity(this, true);
239        isbutton=true;
240      }
241      break;
242    case GDK_BUTTON_RELEASE:
243      if(canvas.getActualTool()!=CREATE_NODE)
244      {
245        canvas.toggleArcActivity(this, false);
246        isbutton=false;
247      }
248      break;
249    case GDK_MOTION_NOTIFY:
250      if(isbutton)
251      {
252        canvas.mytab.mapstorage->setArrowCoords(arc, XY(e->motion.x, e->motion.y));
253
254        draw();
255        canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));
256      }
257    default: break;
258  }
259  return true;
260}
Note: See TracBrowser for help on using the repository browser.