diff -r ee5959aa4410 -r c280de819a73 src/work/peter/graph-displayer.cc --- a/src/work/peter/graph-displayer.cc Sun Apr 17 18:57:22 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,285 +0,0 @@ -// 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 -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace lemon; - -typedef xy Coordinates; -typedef ListGraph Graph; -typedef Graph::NodeMap 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, Node n); - - ///The graph, on which we work - Graph g; - ///Map of nodes of planefigure - Graph::NodeMap nodesmap; - ///Map of edges of planefigure - Graph::EdgeMap edgesmap; - ///Group of graphical elements of displayed_graph - Gnome::Canvas::Group displayed_graph; - - ///Indicates whether the button of mouse is pressed or not - bool isbutton; - - ///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; - - -}; - - -///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, Node n) -{ - 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 dx=e->motion.x-clicked_x; - double dy=e->motion.y-clicked_y; - active_item->move(dx, dy); - clicked_x=e->motion.x; - clicked_y=e->motion.y; - - EdgeIt e; - - g.firstOut(e,n); - for(;e!=INVALID;g.nextOut(e)) - { - Gnome::Canvas::Points coos; - double x1, x2, y1, y2; - - nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2); - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); - - nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2); - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); - - edgesmap[e]->property_points().set_value(coos); - } - - g.firstIn(e,n); - for(;e!=INVALID;g.nextIn(e)) - { - Gnome::Canvas::Points coos; - double x1, x2, y1, y2; - - nodesmap[g.source(e)]->get_bounds(x1, y1, x2, y2); - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); - - nodesmap[g.target(e)]->get_bounds(x1, y1, x2, y2); - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); - - edgesmap[e]->property_points().set_value(coos); - } - } - default: break; - } - return true; -} - -GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & gr, CoordinatesMap & cm):g(gr),nodesmap(g),edgesmap(g),displayed_graph(*(root()), 0, 0),isbutton(false),active_item(NULL) -{ - for (EdgeIt i(g); i!=INVALID; ++i) - { - Gnome::Canvas::Points coos; - coos.push_back(Gnome::Art::Point(cm[g.source(i)].x,cm[g.source(i)].y)); - coos.push_back(Gnome::Art::Point(cm[g.target(i)].x,cm[g.target(i)].y)); - edgesmap[i]=new Gnome::Canvas::Line(displayed_graph, coos); - *(edgesmap[i]) << Gnome::Canvas::Properties::fill_color("green"); - edgesmap[i]->property_width_pixels().set_value(10); - } - for (NodeIt i(g); i!=INVALID; ++i) - { - nodesmap[i]=new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20); - *(nodesmap[i]) << Gnome::Canvas::Properties::fill_color("blue"); - *(nodesmap[i]) << Gnome::Canvas::Properties::outline_color("black"); - (nodesmap[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),i)); - } - -} - -GraphDisplayerCanvas::~GraphDisplayerCanvas() -{ - Graph::NodeMap id(g); - Graph::NodeMap xc(g); - Graph::NodeMap yc(g); - - int j=1; - - for (NodeIt i(g); i!=INVALID; ++i) - { - double x1,y1,x2,y2; - nodesmap[i]->get_bounds(x1, y1, x2, y2); - - id[i]=j++; - xc[i]=(x1+x2)/2; - yc[i]=(y1+y2)/2; - } - - GraphWriter writer(std::cout,g); - - writer.addNodeMap("id", id); - writer.addNodeMap("coordinates_x", xc); - writer.addNodeMap("coordinates_y", yc); - writer.run(); -} - - -//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 -{ - 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[]) -{ - if(argc<2) - { - std::cerr << "USAGE: gd " << endl; - return 0; - } - - Coordinates coosvector; - - Graph g; - - CoordinatesMap cm(g); - Graph::EdgeMap cap(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(argv[1]); - - GraphReader reader(is, g); - reader.addNodeMap("coordinates_x", xreader); - reader.addNodeMap("coordinates_y", yreader); - reader.run(); - - Gnome::Canvas::init(); - Gtk::Main app(argc, argv); - - MainWin mainwin("Displayed Graph", g, cm); - app.run(mainwin); - - return 0; -}