COIN-OR::LEMON - Graph Library

Changeset 147:10ef59f6633c in glemon-0.x


Ignore:
Timestamp:
09/13/06 11:16:29 (13 years ago)
Author:
Akos Ladanyi
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/glemon/trunk@2943
Message:

Loop edges.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • gdc-broken_edge.cc

    r98 r147  
    22#include <cmath>
    33
    4 GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc) : Line(g), edge(_edge), gdc(gc), isbutton(false)
    5 {
    6   arrow=new Gnome::Canvas::Polygon(g);
    7   *arrow << Gnome::Canvas::Properties::fill_color("red");
    8   arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
    9   arrow->lower_to_bottom();
     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
    1059  draw();
    1160}
     
    1362GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
    1463{
    15   if(arrow)delete(arrow);
    1664}
    1765
    1866void GraphDisplayerCanvas::BrokenEdge::draw()
    1967{
    20   MapStorage& ms = gdc.mytab.mapstorage;
     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);
    2181
    2282  // 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)
    2398  {
    24     Gnome::Canvas::Points points;
    25     Node source = ms.graph.source(edge);
    26     Node target = ms.graph.target(edge);
    27     points.push_back(Gnome::Art::Point(ms.coords[source].x,
    28           ms.coords[source].y));
    29     points.push_back(Gnome::Art::Point(ms.arrow_pos[edge].x,
    30           ms.arrow_pos[edge].y));
    31     points.push_back(Gnome::Art::Point(ms.coords[target].x,
    32           ms.coords[target].y));
    33     property_points().set_value(points);
    34   }
    35 
    36   // update the arrow
    37   {
    38     //calculating coordinates of the direction indicator arrow
    39     XY target(ms.coords[ms.graph.target(edge)]);
    40     XY center(ms.arrow_pos[edge]);
    41 
    42     XY unit_vector_in_dir(target-center);
    43     double length=sqrt( unit_vector_in_dir.normSquare() );
    44 
    45     //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
    46     unit_vector_in_dir/=length;
    47     //       std::cout << " = " << unit_vector_in_dir << std::endl;
    48 
    49     XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
    50     //       std::cout << unit_norm_vector << std::endl;
    51 
    52     {     
    53       //       /\       // top
    54       //      /  \      //
    55       //      -  -      // c(enter)l(eft), ccl, ccr, cr
    56       //       ||       //
    57       //       ||       // b(ottom)l, br
    58     }
    59 
    60     double size=3;
    61 
    62     XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
    63     XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
    64     XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
    65     XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
    66     XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
    67     XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
    68     XY top(center + unit_vector_in_dir * 3 * size);
    69 
    70     //std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
    71 
    72     Gnome::Canvas::Points arrow_points;
    73     arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
    74     arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
    75     arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
    76     arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
    77     arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
    78     arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
    79     arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
    80 
    81     arrow->property_points().set_value(arrow_points);
    82   }
    83 }
    84 
    85 bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
    86 {
    87   switch(e->type)
    88     {
    8999    case GDK_BUTTON_PRESS:
    90       //we mark the location of the event to be able to calculate parameters of dragging
    91       if(gdc.getActualTool()!=CREATE_NODE)
    92         {
    93           gdc.toggleEdgeActivity(this, true);
    94           clicked_x=e->button.x;
    95           clicked_y=e->button.y;
    96           isbutton=true;
    97         }
     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      }
    98109      break;
    99110    case GDK_BUTTON_RELEASE:
    100       if(gdc.getActualTool()!=CREATE_NODE)
    101         {
    102           gdc.toggleEdgeActivity(this, false);
    103           isbutton=false;
    104         }
     111      if(canvas.getActualTool()!=CREATE_NODE)
     112      {
     113        canvas.toggleEdgeActivity(this, false);
     114        isbutton=false;
     115      }
    105116      break;
    106117    case GDK_MOTION_NOTIFY:
    107118      //we only have to do sg. if the mouse button is pressed
    108119      if(isbutton)
    109         {
    110           //new coordinates will be the old values,
    111           //because the item will be moved to the
    112           //new coordinate therefore the new movement
    113           //has to be calculated from here
    114 
    115           double dx=e->motion.x-clicked_x;
    116           double dy=e->motion.y-clicked_y;
    117 
    118           Gnome::Canvas::Points points_new;
    119 
    120           gdc.mytab.mapstorage.arrow_pos.set(edge, gdc.mytab.mapstorage.arrow_pos[edge] + XY(dx, dy));
    121 
    122           draw();
    123           gdc.textReposition(gdc.mytab.mapstorage.arrow_pos[edge]);
    124 
    125           clicked_x=e->motion.x;
    126           clicked_y=e->motion.y;
    127 
    128         }
     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      }
    129140    default: break;
    130     }
     141  }
    131142
    132143  return true;
    133144}
     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}
  • graph_displayer_canvas-edge.cc

    r96 r147  
    2525              w=(int)(MIN_EDGE_WIDTH+(v-min)/(max-min)*(MAX_EDGE_WIDTH-MIN_EDGE_WIDTH));
    2626            }
    27           edgesmap[i]->property_width_units().set_value(w);
     27          edgesmap[i]->setLineWidth(w);
    2828        }
    2929    }
     
    3333      if(w>=0)
    3434        {
    35           edgesmap[edge]->property_width_units().set_value(w);
     35          edgesmap[edge]->setLineWidth(w);
    3636        }
    3737    }
     
    6363              w=(int)(MIN_EDGE_WIDTH+(v-min)/(max-min)*(MAX_EDGE_WIDTH-MIN_EDGE_WIDTH));
    6464            }
    65           edgesmap[i]->property_width_units().set_value(w);
     65          edgesmap[i]->setLineWidth(w);
    6666        }
    6767    }
     
    7171      if(w>=0)
    7272        {
    73           edgesmap[edge]->property_width_units().set_value(w);
     73          edgesmap[edge]->setLineWidth(w);
    7474        }
    7575    }
     
    106106              color.set_rgb_p (0, 100, 0);
    107107            }
    108           edgesmap[i]->property_fill_color_gdk().set_value(color);
     108          edgesmap[i]->setFillColor(color);
    109109        }
    110110    }
     
    124124        }
    125125
    126       edgesmap[edge]->property_fill_color_gdk().set_value(color);
     126      edgesmap[edge]->setFillColor(color);
    127127    }
    128128  return 0;
     
    157157              color.set_rgb_p (0, 100, 0);
    158158            }
    159           edgesmap[i]->property_fill_color_gdk().set_value(color);
     159          edgesmap[i]->setFillColor(color);
    160160        }
    161161    }
     
    175175        }
    176176
    177       edgesmap[edge]->property_fill_color_gdk().set_value(color);
     177      edgesmap[edge]->setFillColor(color);
    178178    }
    179179  return 0;
  • graph_displayer_canvas-event.cc

    r134 r147  
    463463              edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge,
    464464                  *this);
    465               *(edgesmap[active_edge]) <<
    466                 Gnome::Canvas::Properties::fill_color("green");
    467               edgesmap[active_edge]->property_width_pixels().set_value(10);
    468 
    469               edgesmap[active_edge]->lower_to_bottom();
    470465
    471466              //initializing edge-text as well, to empty string
     
    830825}
    831826
    832 void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
     827void GraphDisplayerCanvas::toggleEdgeActivity(EdgeBase* active_bre, bool on)
    833828{
    834829  if(on)
    835     {
    836       if(forming_edge!=INVALID)
    837         {
    838           std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
    839         }
    840       else
    841         {
    842           for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
    843             {
    844               if(edgesmap[i]==active_bre)
    845                 {
    846                   forming_edge=i;
    847                 }
    848             }
    849         }
    850     }
     830  {
     831    if(forming_edge!=INVALID)
     832    {
     833      std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
     834    }
     835    else
     836    {
     837      for (EdgeIt i((mytab.mapstorage).graph); i!=INVALID; ++i)
     838      {
     839        if(edgesmap[i]==active_bre)
     840        {
     841          forming_edge=i;
     842        }
     843      }
     844    }
     845  }
    851846  else
    852     {
    853       if(forming_edge!=INVALID)
    854         {
    855           forming_edge=INVALID;
    856         }
    857       else
    858         {
    859           std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
    860         }
    861     }
    862 }
     847  {
     848    if(forming_edge!=INVALID)
     849    {
     850      forming_edge=INVALID;
     851    }
     852    else
     853    {
     854      std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
     855    }
     856  }
     857}
  • graph_displayer_canvas.cc

    r118 r147  
    170170   
    171171    edgesmap[i]=new BrokenEdge(displayed_graph, i, *this);
    172     *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");
    173     edgesmap[i]->property_width_units().set_value(10);   
    174     edgesmap[i]->lower_to_bottom();
    175172   
    176173    //initializing edge-text as well, to empty string
  • graph_displayer_canvas.h

    r127 r147  
    1616{
    1717  friend class BrokenEdge;
     18  friend class LoopEdge;
     19
     20  class EdgeBase : public Gnome::Canvas::Group
     21  {
     22    protected:
     23      ///Reference to the canvas, on which the graph is drawn.
     24
     25      ///It is needed, because some datas needed from
     26      ///graph can be accessed by this or should be sent
     27      ///as parameter, but it would be complicated
     28      GraphDisplayerCanvas& canvas;
     29
     30      ///The edge that the class displays.
     31
     32      ///It is needed, because some datas needed from
     33      ///graph can be accessed by this or should be sent
     34      ///as parameter, but it would be complicated
     35      Edge edge;
     36
     37      Gnome::Canvas::Polygon arrow;
     38
     39      void drawArrow(XY);
     40    public:
     41      EdgeBase(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&);
     42      virtual ~EdgeBase();
     43      virtual void draw() = 0;
     44      virtual void setLineWidth(int) = 0;
     45      virtual void setFillColor(Gdk::Color) = 0;
     46  };
    1847
    1948  ///Edge displayer class
     
    2453  ///and to be able to display more then one edges between the
    2554  ///same source and target
    26   class BrokenEdge : public Gnome::Canvas::Line
     55  class BrokenEdge : public EdgeBase
    2756  {
    28     ///The edge that the class displays.
    29 
    30     ///It is needed, because some datas needed from
    31     ///graph can be accessed by this or should be sent
    32     ///as parameter, but it would be complicated
    33     Edge edge;
    34 
    35     ///Reference to the canvas, on which the graph is drawn.
    36 
    37     ///It is needed, because some datas needed from
    38     ///graph can be accessed by this or should be sent
    39     ///as parameter, but it would be complicated
    40     GraphDisplayerCanvas & gdc;
    41 
    42     ///An arrow that indicates the direction of the edges
    43 
    44     ///in case of directional graph direction can be indicated
    45     ///by this polygon. The polygon formulates a red arrow.
    46     Gnome::Canvas::Polygon * arrow;
    47 
    48     ///Indicates whether the button of mouse is pressed or not at the moment.
    49     bool isbutton;
    50 
    51     ///At this location was the mousebutton pressed. Horizontal component.
    52 
    53     ///It helps to calculate the
    54     ///distance of dragging.
    55     double clicked_x;
    56 
    57     ///At this location was the mousebutton pressed. Vertical component.
    58 
    59     ///It helps to calculate the
    60     ///distance of dragging.
    61     double clicked_y;
    62 
    63     ///event handler for forming broken edges
    64 
    65     ///\param event the
    66     ///event to handle
    67     bool edgeFormerEventHandler(GdkEvent* event);
    68   public:
    69 
    70     ///Constructor of broken edge class.
    71 
    72     ///\param g the group to which the edge belongs
    73     ///\param _edge the represented edge
    74     ///\param gc the canvas
    75     BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc);
    76 
    77     ///Destructor of broken edge class
    78 
    79     ///Frees up
    80     ///reserved memory
    81     ~BrokenEdge();
    82 
    83     ///The function that draws the edge based on collected data
    84     void draw();
     57    private:
     58      Gnome::Canvas::Line line;
     59
     60      ///Indicates whether the button of mouse is pressed or not at the moment.
     61      bool isbutton;
     62
     63      ///At this location was the mousebutton pressed. Horizontal component.
     64
     65      ///It helps to calculate the
     66      ///distance of dragging.
     67      double clicked_x;
     68
     69      ///At this location was the mousebutton pressed. Vertical component.
     70
     71      ///It helps to calculate the
     72      ///distance of dragging.
     73      double clicked_y;
     74
     75      ///event handler for forming broken edges
     76
     77      ///\param event the
     78      ///event to handle
     79      bool edgeFormerEventHandler(GdkEvent* event);
     80
     81    public:
     82      ///Constructor of broken edge class.
     83
     84      ///\param g the group to which the edge belongs
     85      ///\param _edge the represented edge
     86      ///\param gc the canvas
     87      BrokenEdge(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&);
     88
     89      ///Destructor of broken edge class
     90
     91      ///Frees up
     92      ///reserved memory
     93      ~BrokenEdge();
     94
     95      ///The function that draws the edge based on collected data
     96      void draw();
     97
     98      void setLineWidth(int);
     99      void setFillColor(Gdk::Color);
     100  };
     101
     102  class LoopEdge : public EdgeBase
     103  {
     104    private:
     105      Gnome::Canvas::Ellipse line;
     106    public:
     107      LoopEdge(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&);
     108      ~LoopEdge();
     109      void draw();
     110      void setLineWidth(int);
     111      void setFillColor(Gdk::Color);
    85112  };
    86113
     
    242269  void textReposition(xy<double>);
    243270
    244   ///Activates an edge belonging to a BrokenEdge
     271  ///Activates an edge belonging to an EdgeBase
    245272
    246273  ///After we have activated an edge this way,
    247274  ///the GDC object will know, which edge is under forming
    248275  ///therefore it can redraw the necessary elements on the canvas,
    249   ///for example the text belonging to the \ref BrokenEdge can be
     276  ///for example the text belonging to the \ref EdgeBase can be
    250277  ///redrawn (\ref textReposition).
    251   void toggleEdgeActivity(BrokenEdge*, bool);
     278  void toggleEdgeActivity(EdgeBase*, bool);
    252279
    253280public:
     
    290317
    291318  ///Map of edges of graph
    292   Graph::EdgeMap<BrokenEdge *> edgesmap;
     319  Graph::EdgeMap<EdgeBase*> edgesmap;
    293320
    294321  ///Map of texts to write on edges
Note: See TracChangeset for help on using the changeset viewer.