[Lemon-commits] [lemon_svn] hegyi: r1722 - hugo/trunk/src/work/peter
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:47:11 CET 2006
Author: hegyi
Date: Fri Apr 1 11:44:29 2005
New Revision: 1722
Added:
hugo/trunk/src/work/peter/graph-displayer.cc
Log:
Graph displayer is now displaying nodes. Edges remain still undisplayed yet.
Added: hugo/trunk/src/work/peter/graph-displayer.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/peter/graph-displayer.cc Fri Apr 1 11:44:29 2005
@@ -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;
+}
More information about the Lemon-commits
mailing list