3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #include <graph_displayer_canvas.h>
20 #include <mapstorage.h>
24 DigraphDisplayerCanvas::ArcBase::ArcBase(Gnome::Canvas::Group& _group, Arc _arc, DigraphDisplayerCanvas& _canvas) :
25 Gnome::Canvas::Group(_group), arc(_arc), canvas(_canvas), arrow(*this)
27 arrow.property_fill_color().set_value("red");
28 arrow.lower_to_bottom();
32 DigraphDisplayerCanvas::ArcBase::~ArcBase()
36 void DigraphDisplayerCanvas::ArcBase::drawArrow(XY unit_vector_in_dir)
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);
44 // - - // c(enter)l(eft), ccl, ccr, cr
46 // || // b(ottom)l, br
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);
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 ) );
67 arrow.property_points().set_value(arrow_points);
70 DigraphDisplayerCanvas::BrokenArc::BrokenArc(Gnome::Canvas::Group & g,
71 Arc _arc, DigraphDisplayerCanvas & gc) : ArcBase(g, _arc, gc),
72 isbutton(false), line(*this)
74 arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler));
76 line.property_fill_color().set_value("green");
77 line.property_width_units().set_value(10);
78 line.lower_to_bottom();
83 DigraphDisplayerCanvas::BrokenArc::~BrokenArc()
87 void DigraphDisplayerCanvas::BrokenArc::draw()
89 MapStorage& ms = *canvas.mytab.mapstorage;
91 //calculating coordinates of the direction indicator arrow
92 XY head(ms.getNodeCoords(ms.digraph.target(arc)));
93 XY center(ms.getArrowCoords(arc));
95 XY unit_vector_in_dir(head-center);
96 double length=sqrt( unit_vector_in_dir.normSquare() );
100 unit_vector_in_dir/=length;
104 drawArrow(unit_vector_in_dir);
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);
119 bool DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler(GdkEvent* e)
123 case GDK_BUTTON_PRESS:
124 //we mark the location of the event to be able to calculate parameters
126 if(canvas.getActualTool()!=CREATE_NODE)
128 canvas.toggleArcActivity(this, true);
129 clicked_x=e->button.x;
130 clicked_y=e->button.y;
134 case GDK_BUTTON_RELEASE:
135 if(canvas.getActualTool()!=CREATE_NODE)
137 canvas.toggleArcActivity(this, false);
141 case GDK_MOTION_NOTIFY:
142 //we only have to do sg. if the mouse button is pressed
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
150 double dx=e->motion.x-clicked_x;
151 double dy=e->motion.y-clicked_y;
153 Gnome::Canvas::Points points_new;
155 canvas.mytab.mapstorage->setArrowCoords(arc, canvas.mytab.mapstorage->getArrowCoords(arc) + XY(dx, dy));
158 canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));
160 clicked_x=e->motion.x;
161 clicked_y=e->motion.y;
170 void DigraphDisplayerCanvas::BrokenArc::setLineWidth(int w)
172 line.property_width_units().set_value(w);
175 void DigraphDisplayerCanvas::BrokenArc::setFillColor(Gdk::Color c)
177 line.property_fill_color_gdk().set_value(c);
180 DigraphDisplayerCanvas::LoopArc::LoopArc(Gnome::Canvas::Group& _group,
181 Arc _arc, DigraphDisplayerCanvas& _canvas) :
182 ArcBase(_group, _arc, _canvas), line(*this), isbutton(false)
184 arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler));
186 line.property_outline_color().set_value("green");
187 line.property_width_units().set_value(10);
188 line.lower_to_bottom();
193 DigraphDisplayerCanvas::LoopArc::~LoopArc()
197 void DigraphDisplayerCanvas::LoopArc::draw()
199 MapStorage& ms = *canvas.mytab.mapstorage;
201 Node node = ms.digraph.source(arc);
202 XY center = (ms.getNodeCoords(node) + ms.getArrowCoords(arc)) / 2.0;
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;
208 drawArrow(unit_vector_in_dir);
211 sqrt((ms.getArrowCoords(arc) - ms.getNodeCoords(node)).normSquare()) / 2.0;
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);
221 void DigraphDisplayerCanvas::LoopArc::setLineWidth(int w)
223 line.property_width_units().set_value(w);
226 void DigraphDisplayerCanvas::LoopArc::setFillColor(Gdk::Color c)
228 line.property_outline_color_gdk().set_value(c);
231 bool DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler(GdkEvent* e)
235 case GDK_BUTTON_PRESS:
236 if(canvas.getActualTool()!=CREATE_NODE)
238 canvas.toggleArcActivity(this, true);
242 case GDK_BUTTON_RELEASE:
243 if(canvas.getActualTool()!=CREATE_NODE)
245 canvas.toggleArcActivity(this, false);
249 case GDK_MOTION_NOTIFY:
252 canvas.mytab.mapstorage->setArrowCoords(arc, XY(e->motion.x, e->motion.y));
255 canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));