# HG changeset patch # User ladanyi # Date 1158138989 0 # Node ID 10ef59f6633cfb28b6e71b4484df19513d84309c # Parent afd1d8bfcccde056fcc062a1b406cc9151acf8dc Loop edges. diff -r afd1d8bfcccd -r 10ef59f6633c gdc-broken_edge.cc --- a/gdc-broken_edge.cc Wed Aug 30 15:55:18 2006 +0000 +++ b/gdc-broken_edge.cc Wed Sep 13 09:16:29 2006 +0000 @@ -1,133 +1,203 @@ #include "graph_displayer_canvas.h" #include -GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc) : Line(g), edge(_edge), gdc(gc), isbutton(false) +GraphDisplayerCanvas::EdgeBase::EdgeBase(Gnome::Canvas::Group& _group, Edge _edge, GraphDisplayerCanvas& _canvas) : + Gnome::Canvas::Group(_group), edge(_edge), canvas(_canvas), arrow(*this) { - arrow=new Gnome::Canvas::Polygon(g); - *arrow << Gnome::Canvas::Properties::fill_color("red"); - arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler)); - arrow->lower_to_bottom(); + arrow.property_fill_color().set_value("red"); + arrow.lower_to_bottom(); +} + +GraphDisplayerCanvas::EdgeBase::~EdgeBase() +{ +} + +void GraphDisplayerCanvas::EdgeBase::drawArrow(XY unit_vector_in_dir) +{ + MapStorage& ms = canvas.mytab.mapstorage; + XY center(ms.arrow_pos[edge]); + XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x); + + // /\ // top + // / \ // + // - - // c(enter)l(eft), ccl, ccr, cr + // || // + // || // b(ottom)l, br + + double size=3; + + XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size ); + XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size ); + XY ccl(center + unit_vector_in_dir * size + unit_norm_vector * size ); + XY ccr(center + unit_vector_in_dir * size - unit_norm_vector * size ); + XY cl (center + unit_vector_in_dir * size + unit_norm_vector * 2 * size ); + XY cr (center + unit_vector_in_dir * size - unit_norm_vector * 2 * size ); + XY top(center + unit_vector_in_dir * 3 * size); + + Gnome::Canvas::Points arrow_points; + arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y ) ); + arrow_points.push_back(Gnome::Art::Point( br.x , br.y ) ); + arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) ); + arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y ) ); + arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) ); + arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y ) ); + arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) ); + + arrow.property_points().set_value(arrow_points); +} + +GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, + Edge _edge, GraphDisplayerCanvas & gc) : EdgeBase(g, _edge, gc), + isbutton(false), line(*this) +{ + arrow.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler)); + + line.property_fill_color().set_value("green"); + line.property_width_units().set_value(10); + line.lower_to_bottom(); + draw(); } GraphDisplayerCanvas::BrokenEdge::~BrokenEdge() { - if(arrow)delete(arrow); } void GraphDisplayerCanvas::BrokenEdge::draw() { - MapStorage& ms = gdc.mytab.mapstorage; + MapStorage& ms = canvas.mytab.mapstorage; + + //calculating coordinates of the direction indicator arrow + XY head(ms.coords[ms.graph.target(edge)]); + XY center(ms.arrow_pos[edge]); + + XY unit_vector_in_dir(head-center); + double length=sqrt( unit_vector_in_dir.normSquare() ); + + unit_vector_in_dir/=length; + + // update the arrow + drawArrow(unit_vector_in_dir); // update the edge - { - Gnome::Canvas::Points points; - Node source = ms.graph.source(edge); - Node target = ms.graph.target(edge); - points.push_back(Gnome::Art::Point(ms.coords[source].x, - ms.coords[source].y)); - points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x, - ms.arrow_pos[edge].y)); - points.push_back(Gnome::Art::Point(ms.coords[target].x, - ms.coords[target].y)); - property_points().set_value(points); - } - - // update the arrow - { - //calculating coordinates of the direction indicator arrow - XY target(ms.coords[ms.graph.target(edge)]); - XY center(ms.arrow_pos[edge]); - - XY unit_vector_in_dir(target-center); - double length=sqrt( unit_vector_in_dir.normSquare() ); - - // std::cout << target << " - " << center << " = " << unit_vector_in_dir << " / " <property_points().set_value(arrow_points); - } + Gnome::Canvas::Points points; + Node source = ms.graph.source(edge); + Node target = ms.graph.target(edge); + points.push_back(Gnome::Art::Point(ms.coords[source].x, + ms.coords[source].y)); + points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x, + ms.arrow_pos[edge].y)); + points.push_back(Gnome::Art::Point(ms.coords[target].x, + ms.coords[target].y)); + line.property_points().set_value(points); } bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e) { switch(e->type) - { + { case GDK_BUTTON_PRESS: - //we mark the location of the event to be able to calculate parameters of dragging - if(gdc.getActualTool()!=CREATE_NODE) - { - gdc.toggleEdgeActivity(this, true); - clicked_x=e->button.x; - clicked_y=e->button.y; - isbutton=true; - } + //we mark the location of the event to be able to calculate parameters + //of dragging + if(canvas.getActualTool()!=CREATE_NODE) + { + canvas.toggleEdgeActivity(this, true); + clicked_x=e->button.x; + clicked_y=e->button.y; + isbutton=true; + } break; case GDK_BUTTON_RELEASE: - if(gdc.getActualTool()!=CREATE_NODE) - { - gdc.toggleEdgeActivity(this, false); - isbutton=false; - } + if(canvas.getActualTool()!=CREATE_NODE) + { + canvas.toggleEdgeActivity(this, false); + isbutton=false; + } break; case GDK_MOTION_NOTIFY: //we only have to do sg. if the mouse button is pressed if(isbutton) - { - //new coordinates will be the old values, - //because the item will be moved to the - //new coordinate therefore the new movement - //has to be calculated from here + { + //new coordinates will be the old values, + //because the item will be moved to the + //new coordinate therefore the new movement + //has to be calculated from here - double dx=e->motion.x-clicked_x; - double dy=e->motion.y-clicked_y; + double dx=e->motion.x-clicked_x; + double dy=e->motion.y-clicked_y; - Gnome::Canvas::Points points_new; + Gnome::Canvas::Points points_new; - gdc.mytab.mapstorage.arrow_pos.set(edge, gdc.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy)); + canvas.mytab.mapstorage.arrow_pos.set(edge, canvas.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy)); - draw(); - gdc.textReposition(gdc.mytab.mapstorage.arrow_pos[edge]); + draw(); + canvas.textReposition(canvas.mytab.mapstorage.arrow_pos[edge]); - clicked_x=e->motion.x; - clicked_y=e->motion.y; + clicked_x=e->motion.x; + clicked_y=e->motion.y; - } + } default: break; - } + } return true; } + +void GraphDisplayerCanvas::BrokenEdge::setLineWidth(int w) +{ + line.property_width_units().set_value(w); +} + +void GraphDisplayerCanvas::BrokenEdge::setFillColor(Gdk::Color c) +{ + line.property_fill_color_gdk().set_value(c); +} + +GraphDisplayerCanvas::LoopEdge::LoopEdge(Gnome::Canvas::Group& _group, + Edge _edge, GraphDisplayerCanvas& _canvas) : + EdgeBase(_group, _edge, _canvas), line(*this) +{ + line.property_fill_color().set_value("green"); + line.property_width_units().set_value(10); + line.lower_to_bottom(); + + draw(); +} + +GraphDisplayerCanvas::LoopEdge::~LoopEdge() +{ +} + +void GraphDisplayerCanvas::LoopEdge::draw() +{ + MapStorage& ms = canvas.mytab.mapstorage; + + Node node = ms.graph.source(edge); + XY center = (ms.coords[node] + ms.arrow_pos[edge]) / 2.0; + + XY unit_vector_in_dir(rot90(center - ms.arrow_pos[edge])); + double length = sqrt(unit_vector_in_dir.normSquare()); + unit_vector_in_dir /= length; + + drawArrow(unit_vector_in_dir); + + double radius = + sqrt((ms.arrow_pos[edge] - ms.coords[node]).normSquare()) / 2.0; + + XY p1 = center + XY(-radius, radius); + XY p2 = center + XY( radius, -radius); + line.property_x1().set_value(p1.x); + line.property_y1().set_value(p1.y); + line.property_x2().set_value(p2.x); + line.property_y2().set_value(p2.y); +} + +void GraphDisplayerCanvas::LoopEdge::setLineWidth(int w) +{ + line.property_width_units().set_value(w); +} + +void GraphDisplayerCanvas::LoopEdge::setFillColor(Gdk::Color c) +{ + line.property_fill_color_gdk().set_value(c); +} diff -r afd1d8bfcccd -r 10ef59f6633c graph_displayer_canvas-edge.cc --- a/graph_displayer_canvas-edge.cc Wed Aug 30 15:55:18 2006 +0000 +++ b/graph_displayer_canvas-edge.cc Wed Sep 13 09:16:29 2006 +0000 @@ -24,7 +24,7 @@ { w=(int)(MIN_EDGE_WIDTH+(v-min)/(max-min)*(MAX_EDGE_WIDTH-MIN_EDGE_WIDTH)); } - edgesmap[i]->property_width_units().set_value(w); + edgesmap[i]->setLineWidth(w); } } else @@ -32,7 +32,7 @@ int w=(int)actual_map[edge]; if(w>=0) { - edgesmap[edge]->property_width_units().set_value(w); + edgesmap[edge]->setLineWidth(w); } } return 0; @@ -62,7 +62,7 @@ { w=(int)(MIN_EDGE_WIDTH+(v-min)/(max-min)*(MAX_EDGE_WIDTH-MIN_EDGE_WIDTH)); } - edgesmap[i]->property_width_units().set_value(w); + edgesmap[i]->setLineWidth(w); } } else @@ -70,7 +70,7 @@ int w=(int)(*actual_map)[edge]; if(w>=0) { - edgesmap[edge]->property_width_units().set_value(w); + edgesmap[edge]->setLineWidth(w); } } return 0; @@ -105,7 +105,7 @@ { color.set_rgb_p (0, 100, 0); } - edgesmap[i]->property_fill_color_gdk().set_value(color); + edgesmap[i]->setFillColor(color); } } else @@ -123,7 +123,7 @@ color.set_rgb_p (0, 100, 0); } - edgesmap[edge]->property_fill_color_gdk().set_value(color); + edgesmap[edge]->setFillColor(color); } return 0; }; @@ -156,7 +156,7 @@ { color.set_rgb_p (0, 100, 0); } - edgesmap[i]->property_fill_color_gdk().set_value(color); + edgesmap[i]->setFillColor(color); } } else @@ -174,7 +174,7 @@ color.set_rgb_p (0, 100, 0); } - edgesmap[edge]->property_fill_color_gdk().set_value(color); + edgesmap[edge]->setFillColor(color); } return 0; }; diff -r afd1d8bfcccd -r 10ef59f6633c graph_displayer_canvas-event.cc --- a/graph_displayer_canvas-event.cc Wed Aug 30 15:55:18 2006 +0000 +++ b/graph_displayer_canvas-event.cc Wed Sep 13 09:16:29 2006 +0000 @@ -462,11 +462,6 @@ //drawing new edge edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge, *this); - *(edgesmap[active_edge]) << - Gnome::Canvas::Properties::fill_color("green"); - edgesmap[active_edge]->property_width_pixels().set_value(10); - - edgesmap[active_edge]->lower_to_bottom(); //initializing edge-text as well, to empty string XY text_pos=mytab.mapstorage.arrow_pos[active_edge]; @@ -829,34 +824,34 @@ edgetextmap[forming_edge]->property_y().set_value(new_place.y); } -void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on) +void GraphDisplayerCanvas::toggleEdgeActivity(EdgeBase* active_bre, bool on) { if(on) + { + if(forming_edge!=INVALID) { - if(forming_edge!=INVALID) - { - std::cerr << "ERROR!!!! Valid edge found!" << std::endl; - } - else - { - for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) - { - if(edgesmap[i]==active_bre) - { - forming_edge=i; - } - } - } + std::cerr << "ERROR!!!! Valid edge found!" << std::endl; } + else + { + for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i) + { + if(edgesmap[i]==active_bre) + { + forming_edge=i; + } + } + } + } else + { + if(forming_edge!=INVALID) { - if(forming_edge!=INVALID) - { - forming_edge=INVALID; - } - else - { - std::cerr << "ERROR!!!! Invalid edge found!" << std::endl; - } + forming_edge=INVALID; } + else + { + std::cerr << "ERROR!!!! Invalid edge found!" << std::endl; + } + } } diff -r afd1d8bfcccd -r 10ef59f6633c graph_displayer_canvas.cc --- a/graph_displayer_canvas.cc Wed Aug 30 15:55:18 2006 +0000 +++ b/graph_displayer_canvas.cc Wed Sep 13 09:16:29 2006 +0000 @@ -169,9 +169,6 @@ (mytab.mapstorage).coords[(mytab.mapstorage).graph.target(i)].y)); edgesmap[i]=new BrokenEdge(displayed_graph, i, *this); - *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green"); - edgesmap[i]->property_width_units().set_value(10); - edgesmap[i]->lower_to_bottom(); //initializing edge-text as well, to empty string diff -r afd1d8bfcccd -r 10ef59f6633c graph_displayer_canvas.h --- a/graph_displayer_canvas.h Wed Aug 30 15:55:18 2006 +0000 +++ b/graph_displayer_canvas.h Wed Sep 13 09:16:29 2006 +0000 @@ -15,6 +15,35 @@ class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA { friend class BrokenEdge; + friend class LoopEdge; + + class EdgeBase : public Gnome::Canvas::Group + { + protected: + ///Reference to the canvas, on which the graph is drawn. + + ///It is needed, because some datas needed from + ///graph can be accessed by this or should be sent + ///as parameter, but it would be complicated + GraphDisplayerCanvas& canvas; + + ///The edge that the class displays. + + ///It is needed, because some datas needed from + ///graph can be accessed by this or should be sent + ///as parameter, but it would be complicated + Edge edge; + + Gnome::Canvas::Polygon arrow; + + void drawArrow(XY); + public: + EdgeBase(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&); + virtual ~EdgeBase(); + virtual void draw() = 0; + virtual void setLineWidth(int) = 0; + virtual void setFillColor(Gdk::Color) = 0; + }; ///Edge displayer class @@ -23,65 +52,63 @@ ///aim of this is to be able to indicate direction of edges ///and to be able to display more then one edges between the ///same source and target - class BrokenEdge : public Gnome::Canvas::Line + class BrokenEdge : public EdgeBase { - ///The edge that the class displays. + private: + Gnome::Canvas::Line line; - ///It is needed, because some datas needed from - ///graph can be accessed by this or should be sent - ///as parameter, but it would be complicated - Edge edge; + ///Indicates whether the button of mouse is pressed or not at the moment. + bool isbutton; - ///Reference to the canvas, on which the graph is drawn. + ///At this location was the mousebutton pressed. Horizontal component. - ///It is needed, because some datas needed from - ///graph can be accessed by this or should be sent - ///as parameter, but it would be complicated - GraphDisplayerCanvas & gdc; + ///It helps to calculate the + ///distance of dragging. + double clicked_x; - ///An arrow that indicates the direction of the edges + ///At this location was the mousebutton pressed. Vertical component. - ///in case of directional graph direction can be indicated - ///by this polygon. The polygon formulates a red arrow. - Gnome::Canvas::Polygon * arrow; + ///It helps to calculate the + ///distance of dragging. + double clicked_y; - ///Indicates whether the button of mouse is pressed or not at the moment. - bool isbutton; + ///event handler for forming broken edges - ///At this location was the mousebutton pressed. Horizontal component. + ///\param event the + ///event to handle + bool edgeFormerEventHandler(GdkEvent* event); - ///It helps to calculate the - ///distance of dragging. - double clicked_x; + public: + ///Constructor of broken edge class. - ///At this location was the mousebutton pressed. Vertical component. + ///\param g the group to which the edge belongs + ///\param _edge the represented edge + ///\param gc the canvas + BrokenEdge(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&); - ///It helps to calculate the - ///distance of dragging. - double clicked_y; + ///Destructor of broken edge class - ///event handler for forming broken edges + ///Frees up + ///reserved memory + ~BrokenEdge(); - ///\param event the - ///event to handle - bool edgeFormerEventHandler(GdkEvent* event); - public: + ///The function that draws the edge based on collected data + void draw(); - ///Constructor of broken edge class. + void setLineWidth(int); + void setFillColor(Gdk::Color); + }; - ///\param g the group to which the edge belongs - ///\param _edge the represented edge - ///\param gc the canvas - BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc); - - ///Destructor of broken edge class - - ///Frees up - ///reserved memory - ~BrokenEdge(); - - ///The function that draws the edge based on collected data - void draw(); + class LoopEdge : public EdgeBase + { + private: + Gnome::Canvas::Ellipse line; + public: + LoopEdge(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&); + ~LoopEdge(); + void draw(); + void setLineWidth(int); + void setFillColor(Gdk::Color); }; ///Type of canvas, on which the graph is drawn @@ -241,14 +268,14 @@ ///Moves the text to new place void textReposition(xy); - ///Activates an edge belonging to a BrokenEdge + ///Activates an edge belonging to an EdgeBase ///After we have activated an edge this way, ///the GDC object will know, which edge is under forming ///therefore it can redraw the necessary elements on the canvas, - ///for example the text belonging to the \ref BrokenEdge can be + ///for example the text belonging to the \ref EdgeBase can be ///redrawn (\ref textReposition). - void toggleEdgeActivity(BrokenEdge*, bool); + void toggleEdgeActivity(EdgeBase*, bool); public: @@ -289,7 +316,7 @@ Graph::NodeMap nodesmap; ///Map of edges of graph - Graph::EdgeMap edgesmap; + Graph::EdgeMap edgesmap; ///Map of texts to write on edges Graph::EdgeMap edgetextmap;