Graph displayer is now displaying nodes. Edges remain still undisplayed yet.
authorhegyi
Fri, 01 Apr 2005 09:44:29 +0000
changeset 1289142633fc5014
parent 1288 6cc7b573b7b5
child 1290 082fc511c2b9
Graph displayer is now displaying nodes. Edges remain still undisplayed yet.
src/work/peter/graph-displayer.cc
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/work/peter/graph-displayer.cc	Fri Apr 01 09:44:29 2005 +0000
     1.3 @@ -0,0 +1,312 @@
     1.4 +// This example was started by Guillaume Laurent.
     1.5 +// It has become a place to dump code that tests parts of the
     1.6 +// gnomemm canvas code. Little thought has been given to the
     1.7 +// actual on-screen output.
     1.8 +
     1.9 +#include <libgnomecanvasmm.h>
    1.10 +#include <libgnomecanvasmm/polygon.h>
    1.11 +
    1.12 +#include <fstream>
    1.13 +#include <iostream>
    1.14 +
    1.15 +#include <lemon/list_graph.h>
    1.16 +#include <lemon/graph_reader.h>
    1.17 +#include <lemon/graph_utils.h>
    1.18 +#include <lemon/maps.h>
    1.19 +#include <lemon/error.h>
    1.20 +#include <lemon/xy.h>
    1.21 +
    1.22 +using namespace lemon;
    1.23 +
    1.24 +typedef xy<double> Coordinates;
    1.25 +typedef ListGraph Graph;
    1.26 +typedef Graph::NodeMap<Coordinates> CoordinatesMap;
    1.27 +typedef Graph::Node Node;
    1.28 +typedef Graph::EdgeIt EdgeIt;
    1.29 +typedef Graph::NodeIt NodeIt;
    1.30 +
    1.31 +class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
    1.32 +{
    1.33 +  typedef Gnome::Canvas::CanvasAA Parent;
    1.34 +
    1.35 +public:
    1.36 +  GraphDisplayerCanvas(Graph &, CoordinatesMap &);
    1.37 +  virtual ~GraphDisplayerCanvas();
    1.38 +
    1.39 +private:
    1.40 +
    1.41 +  ///Event handler function that handles dragging nodes of displayed_graph
    1.42 +  bool event_handler(GdkEvent* e, int b);
    1.43 +
    1.44 +  ///Event handler function that handles dragging displayed_graph
    1.45 +  bool tri_mover(GdkEvent* e);
    1.46 +
    1.47 +  ///Coordinates of Weight Point of tirangle
    1.48 +  Gnome::Art::Point * wp;
    1.49 +  ///Array of nodes of planefigure
    1.50 +  Gnome::Canvas::Ellipse ** nodes;
    1.51 +  ///Sides of planefigure
    1.52 +  Gnome::Canvas::Polygon * sides;
    1.53 +  ///Group of graphical elements of displayed_graph
    1.54 +  Gnome::Canvas::Group displayed_graph;
    1.55 +
    1.56 +  ///Indicates whether the button of mouse is pressed or not
    1.57 +  bool isbutton;
    1.58 +
    1.59 +  ///Number Of Elements - the number of nodes
    1.60 +  int noe;
    1.61 +
    1.62 +  ///Array of coordinates
    1.63 +  double * coordinates;
    1.64 +
    1.65 +  ///At this location was the mousebutton pressed.
    1.66 +  ///It helps to calculate the distance of dragging.
    1.67 +  double clicked_x, clicked_y;
    1.68 +
    1.69 +  ///Remembers which Gnome::Canvas::Item was pressed.
    1.70 +  ///this variable is needed, because
    1.71 +  ///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
    1.72 +  ///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
    1.73 +  Gnome::Canvas::Item * active_item;
    1.74 +
    1.75 +
    1.76 +};
    1.77 +
    1.78 +///When we click on the weight point we can drag the whole planefigure. This function resolves it.
    1.79 +bool GraphDisplayerCanvas::tri_mover(GdkEvent* e)
    1.80 +{
    1.81 +  switch(e->type)
    1.82 +  {
    1.83 +    case GDK_BUTTON_PRESS:
    1.84 +      clicked_x=e->button.x;
    1.85 +      clicked_y=e->button.y;
    1.86 +      isbutton=true;
    1.87 +      break;
    1.88 +    case GDK_BUTTON_RELEASE:
    1.89 +      isbutton=false;
    1.90 +      active_item=NULL;
    1.91 +      break;
    1.92 +    case GDK_MOTION_NOTIFY:
    1.93 +      if(isbutton)
    1.94 +      {
    1.95 +        double dx=e->motion.x-clicked_x;
    1.96 +        double dy=e->motion.y-clicked_y;
    1.97 +
    1.98 +        Gnome::Canvas::Points coos;
    1.99 +
   1.100 +        for(int i=0;i<=noe;i++)
   1.101 +        {
   1.102 +          nodes[i]->move(dx,dy);
   1.103 +
   1.104 +          double x=(coordinates[2*i]+=dx);
   1.105 +          double y=(coordinates[2*i+1]+=dy);
   1.106 +
   1.107 +          if(i!=noe)coos.push_back(Gnome::Art::Point(x,y));
   1.108 +
   1.109 +        }
   1.110 +
   1.111 +        clicked_x=e->motion.x;
   1.112 +        clicked_y=e->motion.y;
   1.113 +
   1.114 +        sides->property_points().set_value(coos);
   1.115 +      }
   1.116 +    default: break;
   1.117 +  }
   1.118 +  return true;
   1.119 +}
   1.120 +
   1.121 +///This function moves only one node of displayed_graph,
   1.122 +///but recalculate the location of weight point,
   1.123 +///and also redraw the sides of the planefigure.
   1.124 +bool GraphDisplayerCanvas::event_handler(GdkEvent* e, int b)
   1.125 +{
   1.126 +  switch(e->type)
   1.127 +  {
   1.128 +    case GDK_BUTTON_PRESS:
   1.129 +      clicked_x=e->button.x;
   1.130 +      clicked_y=e->button.y;
   1.131 +      active_item=(get_item_at(e->button.x, e->button.y));
   1.132 +      isbutton=true;
   1.133 +      break;
   1.134 +    case GDK_BUTTON_RELEASE:
   1.135 +      isbutton=false;
   1.136 +      active_item=NULL;
   1.137 +      break;
   1.138 +    case GDK_MOTION_NOTIFY:
   1.139 +      if(isbutton)
   1.140 +      {
   1.141 +        //double x1, y1, x2, y2;
   1.142 +        //(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2);
   1.143 +        //printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2);
   1.144 +        //printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y);
   1.145 +        double dx=e->motion.x-clicked_x;
   1.146 +        double dy=e->motion.y-clicked_y;
   1.147 +        active_item->move(dx, dy);
   1.148 +
   1.149 +        coordinates[2*b]+=dx;
   1.150 +        coordinates[2*b+1]+=dy;
   1.151 +
   1.152 +        Gnome::Canvas::Points coos;
   1.153 +
   1.154 +        double x_wp=0;
   1.155 +        double y_wp=0;
   1.156 +
   1.157 +        for(int i=0;i<noe;i++)
   1.158 +        {
   1.159 +          coos.push_back(Gnome::Art::Point(coordinates[2*i], coordinates[2*i+1]));
   1.160 +
   1.161 +          x_wp+=coordinates[2*i];
   1.162 +          y_wp+=coordinates[2*i+1];
   1.163 +        }
   1.164 +
   1.165 +        sides->property_points().set_value(coos);
   1.166 +
   1.167 +        x_wp/=noe;
   1.168 +        y_wp/=noe;
   1.169 +
   1.170 +        dx=x_wp-coordinates[noe*2];
   1.171 +        dy=y_wp-coordinates[noe*2+1];
   1.172 +        nodes[noe]->move(dx, dy);
   1.173 +
   1.174 +        coordinates[noe*2]+=dx;
   1.175 +        coordinates[noe*2+1]+=dy;
   1.176 +
   1.177 +        clicked_x=e->motion.x;
   1.178 +        clicked_y=e->motion.y;
   1.179 +      }
   1.180 +    default: break;
   1.181 +  }
   1.182 +  return true;
   1.183 +}
   1.184 +
   1.185 +GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & g, CoordinatesMap & cm):displayed_graph(*(root()), 0, 0),isbutton(false),active_item(NULL)
   1.186 +{
   1.187 +    nodes=new Gnome::Canvas::Ellipse* [countNodes(g)];
   1.188 +    int sorszam=0;
   1.189 +
   1.190 +    for (NodeIt i(g); i!=INVALID; ++i)
   1.191 +    {
   1.192 +	nodes[sorszam]= new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
   1.193 +	*(nodes[sorszam]) << Gnome::Canvas::Properties::fill_color("blue");
   1.194 +	*(nodes[sorszam]) << Gnome::Canvas::Properties::outline_color("black");
   1.195 +	(nodes[sorszam])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),sorszam));
   1.196 +	sorszam++;
   1.197 +    }
   1.198 +
   1.199 +    for (EdgeIt i(g); i!=INVALID; ++i)
   1.200 +    {
   1.201 +    }
   1.202 +
   1.203 +
   1.204 +}
   1.205 +
   1.206 +GraphDisplayerCanvas::~GraphDisplayerCanvas()
   1.207 +{
   1.208 +}
   1.209 +
   1.210 +//MainWin:
   1.211 +
   1.212 +class MainWin : public Gtk::Window
   1.213 +{
   1.214 +public:
   1.215 +  MainWin(const std::string& title, Graph &, CoordinatesMap &);
   1.216 +
   1.217 +protected:
   1.218 +  //Member widgets:
   1.219 +  GraphDisplayerCanvas gd_canvas;
   1.220 +};
   1.221 +
   1.222 +MainWin::MainWin(const std::string& title, Graph & graph, CoordinatesMap & cm):gd_canvas(graph, cm)
   1.223 +{
   1.224 +  set_title (title);
   1.225 +  add(gd_canvas);
   1.226 +  set_default_size(900,600);
   1.227 +
   1.228 +  show_all();
   1.229 +}
   1.230 +
   1.231 +
   1.232 +///This class is responsible for being able
   1.233 +///to read xy datastructure from file. It is
   1.234 +///based on BaseMap. The set method sets the
   1.235 +///appropriate value in the final xy NodeMap
   1.236 +///that was given to the constructor.
   1.237 +class CoordReaderMap: public MapBase <Node, double>
   1.238 +{
   1.239 +    CoordinatesMap & cm;
   1.240 +    char xoy;
   1.241 +
   1.242 +public:
   1.243 +    CoordReaderMap(char xory, CoordinatesMap & coordmap);
   1.244 +    void set(Node node, double coord);
   1.245 +};
   1.246 +
   1.247 +///The constructor expects for an xy NodeMap,
   1.248 +///and we have to tell it, for which  value
   1.249 +///of the xy vector is responsible the actual
   1.250 +///copy.
   1.251 +CoordReaderMap::CoordReaderMap(char xory, CoordinatesMap & coordmap): cm(coordmap)
   1.252 +{
   1.253 +    switch(xory)
   1.254 +    {
   1.255 +	case 'x':
   1.256 +	case 'y':
   1.257 +	    xoy=xory;
   1.258 +	    break;
   1.259 +	default:
   1.260 +	    throw UninitializedParameter() ;
   1.261 +    }
   1.262 +}
   1.263 +
   1.264 +///set method sets the appropriate value in the
   1.265 +///xy type NodeMap that is under construction
   1.266 +void CoordReaderMap::set(Node node, double coord)
   1.267 +{
   1.268 +    switch(xoy)
   1.269 +    {
   1.270 +	case 'x':
   1.271 +	    cm[node].x=coord;
   1.272 +	    break;
   1.273 +	case 'y':
   1.274 +	    cm[node].y=coord;
   1.275 +	    break;
   1.276 +	default:
   1.277 +	    throw UninitializedParameter() ;
   1.278 +    }
   1.279 +}
   1.280 +
   1.281 +//main():
   1.282 +
   1.283 +int main(int argc, char *argv[])
   1.284 +{
   1.285 +
   1.286 +  Coordinates coosvector;
   1.287 +
   1.288 +  Graph g;
   1.289 +
   1.290 +  CoordinatesMap cm(g);
   1.291 +
   1.292 +  //we create one object to read x coordinates
   1.293 +  //and one to read y coordinate of nodes and write them to cm NodeMap.
   1.294 +  CoordReaderMap xreader('x',cm);
   1.295 +  CoordReaderMap yreader('y',cm);
   1.296 +
   1.297 +  std::ifstream is("graphocska.lemon");
   1.298 +
   1.299 +  GraphReader<Graph> reader(is, g);
   1.300 +  reader.addNodeMap("coordinates_x", xreader);
   1.301 +  reader.addNodeMap("coordinates_y", yreader);
   1.302 +  reader.run();
   1.303 +
   1.304 +  for (NodeIt i(g); i!=INVALID; ++i)
   1.305 +      std::cout << " " << g.id(i) << " " << cm[i];
   1.306 +  std::cout << std::endl;
   1.307 +
   1.308 +  Gnome::Canvas::init();
   1.309 +  Gtk::Main app(argc, argv);
   1.310 +
   1.311 +  MainWin mainwin("Displayed Graph", g, cm);
   1.312 +  app.run(mainwin);
   1.313 +
   1.314 +  return 0;
   1.315 +}