# HG changeset patch
# User hegyi
# Date 1112348669 0
# Node ID 142633fc5014b3e0f84e223a7387fc1e7ab8a8a2
# Parent  6cc7b573b7b569c0bffc437327539882344474ed
Graph displayer is now displaying nodes. Edges remain still undisplayed yet.

diff -r 6cc7b573b7b5 -r 142633fc5014 src/work/peter/graph-displayer.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/work/peter/graph-displayer.cc	Fri Apr 01 09:44:29 2005 +0000
@@ -0,0 +1,312 @@
+// This example was started by Guillaume Laurent.
+// It has become a place to dump code that tests parts of the
+// gnomemm canvas code. Little thought has been given to the
+// actual on-screen output.
+
+#include <libgnomecanvasmm.h>
+#include <libgnomecanvasmm/polygon.h>
+
+#include <fstream>
+#include <iostream>
+
+#include <lemon/list_graph.h>
+#include <lemon/graph_reader.h>
+#include <lemon/graph_utils.h>
+#include <lemon/maps.h>
+#include <lemon/error.h>
+#include <lemon/xy.h>
+
+using namespace lemon;
+
+typedef xy<double> Coordinates;
+typedef ListGraph Graph;
+typedef Graph::NodeMap<Coordinates> CoordinatesMap;
+typedef Graph::Node Node;
+typedef Graph::EdgeIt EdgeIt;
+typedef Graph::NodeIt NodeIt;
+
+class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
+{
+  typedef Gnome::Canvas::CanvasAA Parent;
+
+public:
+  GraphDisplayerCanvas(Graph &, CoordinatesMap &);
+  virtual ~GraphDisplayerCanvas();
+
+private:
+
+  ///Event handler function that handles dragging nodes of displayed_graph
+  bool event_handler(GdkEvent* e, int b);
+
+  ///Event handler function that handles dragging displayed_graph
+  bool tri_mover(GdkEvent* e);
+
+  ///Coordinates of Weight Point of tirangle
+  Gnome::Art::Point * wp;
+  ///Array of nodes of planefigure
+  Gnome::Canvas::Ellipse ** nodes;
+  ///Sides of planefigure
+  Gnome::Canvas::Polygon * sides;
+  ///Group of graphical elements of displayed_graph
+  Gnome::Canvas::Group displayed_graph;
+
+  ///Indicates whether the button of mouse is pressed or not
+  bool isbutton;
+
+  ///Number Of Elements - the number of nodes
+  int noe;
+
+  ///Array of coordinates
+  double * coordinates;
+
+  ///At this location was the mousebutton pressed.
+  ///It helps to calculate the distance of dragging.
+  double clicked_x, clicked_y;
+
+  ///Remembers which Gnome::Canvas::Item was pressed.
+  ///this variable is needed, because
+  ///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
+  ///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
+  Gnome::Canvas::Item * active_item;
+
+
+};
+
+///When we click on the weight point we can drag the whole planefigure. This function resolves it.
+bool GraphDisplayerCanvas::tri_mover(GdkEvent* e)
+{
+  switch(e->type)
+  {
+    case GDK_BUTTON_PRESS:
+      clicked_x=e->button.x;
+      clicked_y=e->button.y;
+      isbutton=true;
+      break;
+    case GDK_BUTTON_RELEASE:
+      isbutton=false;
+      active_item=NULL;
+      break;
+    case GDK_MOTION_NOTIFY:
+      if(isbutton)
+      {
+        double dx=e->motion.x-clicked_x;
+        double dy=e->motion.y-clicked_y;
+
+        Gnome::Canvas::Points coos;
+
+        for(int i=0;i<=noe;i++)
+        {
+          nodes[i]->move(dx,dy);
+
+          double x=(coordinates[2*i]+=dx);
+          double y=(coordinates[2*i+1]+=dy);
+
+          if(i!=noe)coos.push_back(Gnome::Art::Point(x,y));
+
+        }
+
+        clicked_x=e->motion.x;
+        clicked_y=e->motion.y;
+
+        sides->property_points().set_value(coos);
+      }
+    default: break;
+  }
+  return true;
+}
+
+///This function moves only one node of displayed_graph,
+///but recalculate the location of weight point,
+///and also redraw the sides of the planefigure.
+bool GraphDisplayerCanvas::event_handler(GdkEvent* e, int b)
+{
+  switch(e->type)
+  {
+    case GDK_BUTTON_PRESS:
+      clicked_x=e->button.x;
+      clicked_y=e->button.y;
+      active_item=(get_item_at(e->button.x, e->button.y));
+      isbutton=true;
+      break;
+    case GDK_BUTTON_RELEASE:
+      isbutton=false;
+      active_item=NULL;
+      break;
+    case GDK_MOTION_NOTIFY:
+      if(isbutton)
+      {
+        //double x1, y1, x2, y2;
+        //(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2);
+        //printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2);
+        //printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y);
+        double dx=e->motion.x-clicked_x;
+        double dy=e->motion.y-clicked_y;
+        active_item->move(dx, dy);
+
+        coordinates[2*b]+=dx;
+        coordinates[2*b+1]+=dy;
+
+        Gnome::Canvas::Points coos;
+
+        double x_wp=0;
+        double y_wp=0;
+
+        for(int i=0;i<noe;i++)
+        {
+          coos.push_back(Gnome::Art::Point(coordinates[2*i], coordinates[2*i+1]));
+
+          x_wp+=coordinates[2*i];
+          y_wp+=coordinates[2*i+1];
+        }
+
+        sides->property_points().set_value(coos);
+
+        x_wp/=noe;
+        y_wp/=noe;
+
+        dx=x_wp-coordinates[noe*2];
+        dy=y_wp-coordinates[noe*2+1];
+        nodes[noe]->move(dx, dy);
+
+        coordinates[noe*2]+=dx;
+        coordinates[noe*2+1]+=dy;
+
+        clicked_x=e->motion.x;
+        clicked_y=e->motion.y;
+      }
+    default: break;
+  }
+  return true;
+}
+
+GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & g, CoordinatesMap & cm):displayed_graph(*(root()), 0, 0),isbutton(false),active_item(NULL)
+{
+    nodes=new Gnome::Canvas::Ellipse* [countNodes(g)];
+    int sorszam=0;
+
+    for (NodeIt i(g); i!=INVALID; ++i)
+    {
+	nodes[sorszam]= new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
+	*(nodes[sorszam]) << Gnome::Canvas::Properties::fill_color("blue");
+	*(nodes[sorszam]) << Gnome::Canvas::Properties::outline_color("black");
+	(nodes[sorszam])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),sorszam));
+	sorszam++;
+    }
+
+    for (EdgeIt i(g); i!=INVALID; ++i)
+    {
+    }
+
+
+}
+
+GraphDisplayerCanvas::~GraphDisplayerCanvas()
+{
+}
+
+//MainWin:
+
+class MainWin : public Gtk::Window
+{
+public:
+  MainWin(const std::string& title, Graph &, CoordinatesMap &);
+
+protected:
+  //Member widgets:
+  GraphDisplayerCanvas gd_canvas;
+};
+
+MainWin::MainWin(const std::string& title, Graph & graph, CoordinatesMap & cm):gd_canvas(graph, cm)
+{
+  set_title (title);
+  add(gd_canvas);
+  set_default_size(900,600);
+
+  show_all();
+}
+
+
+///This class is responsible for being able
+///to read xy datastructure from file. It is
+///based on BaseMap. The set method sets the
+///appropriate value in the final xy NodeMap
+///that was given to the constructor.
+class CoordReaderMap: public MapBase <Node, double>
+{
+    CoordinatesMap & cm;
+    char xoy;
+
+public:
+    CoordReaderMap(char xory, CoordinatesMap & coordmap);
+    void set(Node node, double coord);
+};
+
+///The constructor expects for an xy NodeMap,
+///and we have to tell it, for which  value
+///of the xy vector is responsible the actual
+///copy.
+CoordReaderMap::CoordReaderMap(char xory, CoordinatesMap & coordmap): cm(coordmap)
+{
+    switch(xory)
+    {
+	case 'x':
+	case 'y':
+	    xoy=xory;
+	    break;
+	default:
+	    throw UninitializedParameter() ;
+    }
+}
+
+///set method sets the appropriate value in the
+///xy type NodeMap that is under construction
+void CoordReaderMap::set(Node node, double coord)
+{
+    switch(xoy)
+    {
+	case 'x':
+	    cm[node].x=coord;
+	    break;
+	case 'y':
+	    cm[node].y=coord;
+	    break;
+	default:
+	    throw UninitializedParameter() ;
+    }
+}
+
+//main():
+
+int main(int argc, char *argv[])
+{
+
+  Coordinates coosvector;
+
+  Graph g;
+
+  CoordinatesMap cm(g);
+
+  //we create one object to read x coordinates
+  //and one to read y coordinate of nodes and write them to cm NodeMap.
+  CoordReaderMap xreader('x',cm);
+  CoordReaderMap yreader('y',cm);
+
+  std::ifstream is("graphocska.lemon");
+
+  GraphReader<Graph> reader(is, g);
+  reader.addNodeMap("coordinates_x", xreader);
+  reader.addNodeMap("coordinates_y", yreader);
+  reader.run();
+
+  for (NodeIt i(g); i!=INVALID; ++i)
+      std::cout << " " << g.id(i) << " " << cm[i];
+  std::cout << std::endl;
+
+  Gnome::Canvas::init();
+  Gtk::Main app(argc, argv);
+
+  MainWin mainwin("Displayed Graph", g, cm);
+  app.run(mainwin);
+
+  return 0;
+}