src/work/peter/graph-displayer.cc
changeset 1345 71e0777b65e0
parent 1290 082fc511c2b9
equal deleted inserted replaced
1:5746a98fbc05 2:df3763d71446
     9 #include <fstream>
     9 #include <fstream>
    10 #include <iostream>
    10 #include <iostream>
    11 
    11 
    12 #include <lemon/list_graph.h>
    12 #include <lemon/list_graph.h>
    13 #include <lemon/graph_reader.h>
    13 #include <lemon/graph_reader.h>
       
    14 #include <lemon/graph_writer.h>
    14 #include <lemon/graph_utils.h>
    15 #include <lemon/graph_utils.h>
    15 #include <lemon/maps.h>
    16 #include <lemon/maps.h>
    16 #include <lemon/error.h>
    17 #include <lemon/error.h>
    17 #include <lemon/xy.h>
    18 #include <lemon/xy.h>
    18 
    19 
    34   virtual ~GraphDisplayerCanvas();
    35   virtual ~GraphDisplayerCanvas();
    35 
    36 
    36 private:
    37 private:
    37 
    38 
    38   ///Event handler function that handles dragging nodes of displayed_graph
    39   ///Event handler function that handles dragging nodes of displayed_graph
    39   bool event_handler(GdkEvent* e, int b);
    40   bool event_handler(GdkEvent* e, Node n);
    40 
    41 
    41   ///Event handler function that handles dragging displayed_graph
    42 	///The graph, on which we work
    42   bool tri_mover(GdkEvent* e);
    43 	Graph g;
    43 
    44   ///Map of nodes of planefigure
    44   ///Coordinates of Weight Point of tirangle
    45   Graph::NodeMap<Gnome::Canvas::Ellipse *> nodesmap;  
    45   Gnome::Art::Point * wp;
    46   ///Map of edges of planefigure
    46   ///Array of nodes of planefigure
    47   Graph::EdgeMap<Gnome::Canvas::Line *> edgesmap;  
    47   Gnome::Canvas::Ellipse ** nodes;
       
    48   ///Sides of planefigure
       
    49   Gnome::Canvas::Polygon * sides;
       
    50   ///Group of graphical elements of displayed_graph
    48   ///Group of graphical elements of displayed_graph
    51   Gnome::Canvas::Group displayed_graph;
    49   Gnome::Canvas::Group displayed_graph;
    52 
    50 
    53   ///Indicates whether the button of mouse is pressed or not
    51   ///Indicates whether the button of mouse is pressed or not
    54   bool isbutton;
    52   bool isbutton;
    55 
       
    56   ///Number Of Elements - the number of nodes
       
    57   int noe;
       
    58 
       
    59   ///Array of coordinates
       
    60   double * coordinates;
       
    61 
    53 
    62   ///At this location was the mousebutton pressed.
    54   ///At this location was the mousebutton pressed.
    63   ///It helps to calculate the distance of dragging.
    55   ///It helps to calculate the distance of dragging.
    64   double clicked_x, clicked_y;
    56   double clicked_x, clicked_y;
    65 
    57 
    70   Gnome::Canvas::Item * active_item;
    62   Gnome::Canvas::Item * active_item;
    71 
    63 
    72 
    64 
    73 };
    65 };
    74 
    66 
    75 ///When we click on the weight point we can drag the whole planefigure. This function resolves it.
       
    76 bool GraphDisplayerCanvas::tri_mover(GdkEvent* e)
       
    77 {
       
    78   switch(e->type)
       
    79   {
       
    80     case GDK_BUTTON_PRESS:
       
    81       clicked_x=e->button.x;
       
    82       clicked_y=e->button.y;
       
    83       isbutton=true;
       
    84       break;
       
    85     case GDK_BUTTON_RELEASE:
       
    86       isbutton=false;
       
    87       active_item=NULL;
       
    88       break;
       
    89     case GDK_MOTION_NOTIFY:
       
    90       if(isbutton)
       
    91       {
       
    92         double dx=e->motion.x-clicked_x;
       
    93         double dy=e->motion.y-clicked_y;
       
    94 
       
    95         Gnome::Canvas::Points coos;
       
    96 
       
    97         for(int i=0;i<=noe;i++)
       
    98         {
       
    99           nodes[i]->move(dx,dy);
       
   100 
       
   101           double x=(coordinates[2*i]+=dx);
       
   102           double y=(coordinates[2*i+1]+=dy);
       
   103 
       
   104           if(i!=noe)coos.push_back(Gnome::Art::Point(x,y));
       
   105 
       
   106         }
       
   107 
       
   108         clicked_x=e->motion.x;
       
   109         clicked_y=e->motion.y;
       
   110 
       
   111         sides->property_points().set_value(coos);
       
   112       }
       
   113     default: break;
       
   114   }
       
   115   return true;
       
   116 }
       
   117 
    67 
   118 ///This function moves only one node of displayed_graph,
    68 ///This function moves only one node of displayed_graph,
   119 ///but recalculate the location of weight point,
    69 ///but recalculate the location of weight point,
   120 ///and also redraw the sides of the planefigure.
    70 ///and also redraw the sides of the planefigure.
   121 bool GraphDisplayerCanvas::event_handler(GdkEvent* e, int b)
    71 bool GraphDisplayerCanvas::event_handler(GdkEvent* e, Node n)
   122 {
    72 {
   123   switch(e->type)
    73   switch(e->type)
   124   {
    74   {
   125     case GDK_BUTTON_PRESS:
    75     case GDK_BUTTON_PRESS:
   126       clicked_x=e->button.x;
    76       clicked_x=e->button.x;
   133       active_item=NULL;
    83       active_item=NULL;
   134       break;
    84       break;
   135     case GDK_MOTION_NOTIFY:
    85     case GDK_MOTION_NOTIFY:
   136       if(isbutton)
    86       if(isbutton)
   137       {
    87       {
   138         //double x1, y1, x2, y2;
       
   139         //(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2);
       
   140         //printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2);
       
   141         //printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y);
       
   142         double dx=e->motion.x-clicked_x;
    88         double dx=e->motion.x-clicked_x;
   143         double dy=e->motion.y-clicked_y;
    89         double dy=e->motion.y-clicked_y;
   144         active_item->move(dx, dy);
    90         active_item->move(dx, dy);
   145 
       
   146         coordinates[2*b]+=dx;
       
   147         coordinates[2*b+1]+=dy;
       
   148 
       
   149         Gnome::Canvas::Points coos;
       
   150 
       
   151         double x_wp=0;
       
   152         double y_wp=0;
       
   153 
       
   154         for(int i=0;i<noe;i++)
       
   155         {
       
   156           coos.push_back(Gnome::Art::Point(coordinates[2*i], coordinates[2*i+1]));
       
   157 
       
   158           x_wp+=coordinates[2*i];
       
   159           y_wp+=coordinates[2*i+1];
       
   160         }
       
   161 
       
   162         sides->property_points().set_value(coos);
       
   163 
       
   164         x_wp/=noe;
       
   165         y_wp/=noe;
       
   166 
       
   167         dx=x_wp-coordinates[noe*2];
       
   168         dy=y_wp-coordinates[noe*2+1];
       
   169         nodes[noe]->move(dx, dy);
       
   170 
       
   171         coordinates[noe*2]+=dx;
       
   172         coordinates[noe*2+1]+=dy;
       
   173 
       
   174         clicked_x=e->motion.x;
    91         clicked_x=e->motion.x;
   175         clicked_y=e->motion.y;
    92         clicked_y=e->motion.y;
       
    93 
       
    94 				EdgeIt e;
       
    95 
       
    96 				g.firstOut(e,n);
       
    97 				for(;e!=INVALID;g.nextOut(e))
       
    98 				{
       
    99 						Gnome::Canvas::Points coos;
       
   100 						double x1, x2, y1, y2;
       
   101 
       
   102 						nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
       
   103 						coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   104 
       
   105 						nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
       
   106 						coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   107 
       
   108 						edgesmap[e]->property_points().set_value(coos);
       
   109 				}
       
   110 
       
   111 				g.firstIn(e,n);
       
   112 				for(;e!=INVALID;g.nextIn(e))
       
   113 				{
       
   114 						Gnome::Canvas::Points coos;
       
   115 						double x1, x2, y1, y2;
       
   116 
       
   117 						nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2);
       
   118 						coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   119 
       
   120 						nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2);
       
   121 						coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
       
   122 
       
   123 						edgesmap[e]->property_points().set_value(coos);
       
   124 				}
   176       }
   125       }
   177     default: break;
   126     default: break;
   178   }
   127   }
   179   return true;
   128   return true;
   180 }
   129 }
   181 
   130 
   182 GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & g, CoordinatesMap & cm):displayed_graph(*(root()), 0, 0),isbutton(false),active_item(NULL)
   131 GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & gr, CoordinatesMap & cm):g(gr),nodesmap(g),edgesmap(g),displayed_graph(*(root()), 0, 0),isbutton(false),active_item(NULL)
   183 {
   132 {
   184     nodes=new Gnome::Canvas::Ellipse* [countNodes(g)];
   133 		for (EdgeIt i(g); i!=INVALID; ++i)
   185     int sorszam=0;
   134     {
   186 
   135 				Gnome::Canvas::Points coos;
       
   136 				coos.push_back(Gnome::Art::Point(cm[g.source(i)].x,cm[g.source(i)].y));
       
   137 				coos.push_back(Gnome::Art::Point(cm[g.target(i)].x,cm[g.target(i)].y));
       
   138 				edgesmap[i]=new Gnome::Canvas::Line(displayed_graph, coos);
       
   139 				*(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green");
       
   140 				edgesmap[i]->property_width_pixels().set_value(10);
       
   141     }
   187     for (NodeIt i(g); i!=INVALID; ++i)
   142     for (NodeIt i(g); i!=INVALID; ++i)
   188     {
   143     {
   189 	nodes[sorszam]= new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
   144 				nodesmap[i]=new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
   190 	*(nodes[sorszam]) << Gnome::Canvas::Properties::fill_color("blue");
   145 				*(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue");
   191 	*(nodes[sorszam]) << Gnome::Canvas::Properties::outline_color("black");
   146 				*(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black");
   192 	(nodes[sorszam])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),sorszam));
   147 				(nodesmap[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),i));
   193 	sorszam++;
   148     }
   194     }
       
   195 
       
   196     for (EdgeIt i(g); i!=INVALID; ++i)
       
   197     {
       
   198     }
       
   199 
       
   200 
   149 
   201 }
   150 }
   202 
   151 
   203 GraphDisplayerCanvas::~GraphDisplayerCanvas()
   152 GraphDisplayerCanvas::~GraphDisplayerCanvas()
   204 {
   153 {
   205 }
   154 		Graph::NodeMap <int> id(g);
       
   155 		Graph::NodeMap <double> xc(g);
       
   156 		Graph::NodeMap <double> yc(g);
       
   157 
       
   158 		int j=1;
       
   159 
       
   160     for (NodeIt i(g); i!=INVALID; ++i)
       
   161     {
       
   162 				double x1,y1,x2,y2;
       
   163 				nodesmap[i]->get_bounds(x1, y1, x2, y2);
       
   164 
       
   165 				id[i]=j++;
       
   166 				xc[i]=(x1+x2)/2;
       
   167 				yc[i]=(y1+y2)/2;
       
   168 		}
       
   169 
       
   170 		GraphWriter<Graph> writer(std::cout,g);
       
   171 
       
   172 		writer.addNodeMap("id", id);
       
   173 		writer.addNodeMap("coordinates_x", xc);
       
   174 		writer.addNodeMap("coordinates_y", yc);
       
   175 		writer.run();
       
   176 }
       
   177 
   206 
   178 
   207 //MainWin:
   179 //MainWin:
   208 
       
   209 class MainWin : public Gtk::Window
   180 class MainWin : public Gtk::Window
   210 {
   181 {
   211 public:
   182 public:
   212   MainWin(const std::string& title, Graph &, CoordinatesMap &);
   183   MainWin(const std::string& title, Graph &, CoordinatesMap &);
   213 
   184 
   288   Coordinates coosvector;
   259   Coordinates coosvector;
   289 
   260 
   290   Graph g;
   261   Graph g;
   291 
   262 
   292   CoordinatesMap cm(g);
   263   CoordinatesMap cm(g);
       
   264   Graph::EdgeMap<double> cap(g);
   293 
   265 
   294   //we create one object to read x coordinates
   266   //we create one object to read x coordinates
   295   //and one to read y coordinate of nodes and write them to cm NodeMap.
   267   //and one to read y coordinate of nodes and write them to cm NodeMap.
   296   CoordReaderMap xreader('x',cm);
   268   CoordReaderMap xreader('x',cm);
   297   CoordReaderMap yreader('y',cm);
   269   CoordReaderMap yreader('y',cm);
   301   GraphReader<Graph> reader(is, g);
   273   GraphReader<Graph> reader(is, g);
   302   reader.addNodeMap("coordinates_x", xreader);
   274   reader.addNodeMap("coordinates_x", xreader);
   303   reader.addNodeMap("coordinates_y", yreader);
   275   reader.addNodeMap("coordinates_y", yreader);
   304   reader.run();
   276   reader.run();
   305 
   277 
   306   for (NodeIt i(g); i!=INVALID; ++i)
       
   307       std::cout << " " << g.id(i) << " " << cm[i];
       
   308   std::cout << std::endl;
       
   309 
       
   310   Gnome::Canvas::init();
   278   Gnome::Canvas::init();
   311   Gtk::Main app(argc, argv);
   279   Gtk::Main app(argc, argv);
   312 
   280 
   313   MainWin mainwin("Displayed Graph", g, cm);
   281   MainWin mainwin("Displayed Graph", g, cm);
   314   app.run(mainwin);
   282   app.run(mainwin);